bash envsubst 可以不进行就地替换吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35078753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can envsubst not do in-place substitution?
提问by peedee
I have a config file which contains some ENV_VARIABLE styled variables.
我有一个包含一些 ENV_VARIABLE 样式变量的配置文件。
This is my file.
It might contain $EXAMPLES of text.
Now I want that variable replaced with a value which is saved in my actual environment variables. So I'm trying this:
现在我想用保存在我的实际环境变量中的值替换该变量。所以我正在尝试这个:
export EXAMPLES=lots
envsubst < file.txt > file.txt
But it doesn't work when the input file and output file are identical. The result is an empty file of size 0.
但是当输入文件和输出文件相同时它不起作用。结果是一个大小为 0 的空文件。
There must be a good reason for this, some bash basics that I'm not aware of? How do I achieve what I want to do, ideally without first outputting to a different file and then replacing the original file with it?
这一定有一个很好的理由,一些我不知道的 bash 基础知识?我如何实现我想要做的事情,最好不要先输出到不同的文件,然后用它替换原始文件?
I know that I can do it easily enough with sed
, but when I discovered the envsubst
command I thought that it should be perfect for my use case, so I'd like to use that.
我知道我可以很容易地使用sed
,但是当我发现该envsubst
命令时,我认为它应该非常适合我的用例,所以我想使用它。
回答by rici
Redirects are handled by the shell, not the program being executed, and they are setup before the program is invoked.
重定向由 shell 处理,而不是由正在执行的程序处理,并且在调用程序之前设置它们。
The redirect >output.file
has the effect of creating output.file
if it doedn't exist and emptying it if it does. Either way, you end up with an empty file, and that is what the program's output is redirected to.
重定向>output.file
的作用是output.file
在它不存在时创建,如果存在则清空它。无论哪种方式,您最终都会得到一个空文件,这就是程序的输出被重定向到的地方。
Programs like sed
which are capable of "in-place" modification must take the filename as a command-line argument, not as a redirect.
程序,如sed
其中“就地”修饰的能够一定要把文件名作为命令行参数,而不是作为一个重定向。
In your case, I would suggest using a temporary file and then renaming it if all went OK.
在你的情况下,我建议使用一个临时文件,如果一切顺利,然后重命名它。
回答by Laine Damien
envsubst < file.txt | tee file.txt
回答by SoftwareFactor
Here is the solution that I use:
这是我使用的解决方案:
tmpfile=$(mktemp)
cat file.txt | envsubst | tee "$tmpfile" && mv "$tmpfile" file.txt
Be careful with other solutions that do not use a temporary file. Pipes are asynchronous, so the file will occasionally be read after tee
has already truncated it.
小心其他不使用临时文件的解决方案。管道是异步的,所以文件在tee
截断之后偶尔会被读取。
回答by Christoph H?sler
You can achieve in-place substitution by calling envsubst from gnu sed with the "e" command:
您可以通过使用“e”命令从 gnu sed 调用 envsubst 来实现就地替换:
EXAMPLES=lots sed -i 's/.*/echo & | envsubst/e' file.txt
回答by peedee
In the end I found that using envsubst
was too dangerous after all. My files might contain dollar signs in places where I don't want any substitution to happen, and envsubst
will just replace them with empty strings if no corresponding environment variable is defined. Not cool.
最后我发现使用envsubst
毕竟太危险了。我的文件可能在我不希望发生任何替换的地方包含美元符号,envsubst
如果没有定义相应的环境变量,我只会用空字符串替换它们。不酷。