envsubst不能进行就地替换吗?

时间:2016-01-29 07:09:44

标签: bash environment-variables

我有一个包含一些ENV_VARIABLE样式变量的配置文件。

This is my file.
It might contain $EXAMPLES of text.

现在我希望将变量替换为保存在实际环境变量中的值。所以我试试这个:

export EXAMPLES=lots
envsubst < file.txt > file.txt

但是当输入文件和输出文件相同时它不起作用。结果是一个大小为0的空文件。

我必须有充分的理由,一些我不知道的bash基础知识? 如何在不首先输出到其他文件然后用它替换原始文件的情况下实现我想要做的事情?

我知道我可以使用sed轻松完成,但当我发现envsubst命令时,我认为它应该适合我的用例,所以我想要用那个。

9 个答案:

答案 0 :(得分:8)

这是我使用的解决方案:

originalfile="file.txt"
tmpfile=$(mktemp)
cp --attributes-only --preserve $originalfile $tmpfile
cat $originalfile | envsubst | tee $tmpfile &&  mv $tmpfile $originalfile

请注意其他不使用临时文件的解决方案。管道是异步的,因此tee截断后偶尔会读取该文件。

答案 1 :(得分:7)

重定向由shell处理,而不是正在执行的程序,并且在调用程序之前设置它们。

重定向#include <stdio.h> int main(void) { int i=10; if(i==(20||10)) printf("True"); else printf("False"); return 0; } 具有创建>output.file的效果(如果它不存在),如果存在则将其清空。无论哪种方式,最终都会得到一个空文件,这就是程序输出被重定向到的位置。

能够进行“就地”修改的output.file等程序必须将文件名作为命令行参数,而不是重定向。

在你的情况下,我会建议使用一个临时文件,然后重命名它,如果一切正常。

答案 2 :(得分:5)

envsubst < file.txt | tee file.txt

答案 3 :(得分:0)

您可以通过使用"e" command从gnu sed调用envsubst来实现就地替换:

EXAMPLES=lots sed -i 's/.*/echo & | envsubst/e' file.txt

答案 4 :(得分:0)

严格来说不是就地,而是:

cat file.txt | envsubst > file.txt

这对我有效(在Mac上)

答案 5 :(得分:0)

值得注意的是,mv解决方案不会维护文件权限。如果您要修改可执行文件,最好使用cp -pf

tmpfile=$(mktemp)
cat file.txt | envsubst > "$tmpfile" && cp -pf "$tmpfile" file.txt
rm -f "$tmpfile"

答案 6 :(得分:0)

这个答案是由另外两个答案构成的。我想这是最好的解决方案。

originalFile=file.txt
tmpfile=$(mktemp)
cat $originalFile | envsubst > "$tmpfile" && cp -pf "$tmpfile" $originalFile
rm -f "$tmpfile"

答案 7 :(得分:0)

我找到了另一个快捷方式放入临时文件,然后将其重命名为原始文件。

envsubst out.txt && mv out.txt in.txt

答案 8 :(得分:-3)

最后我发现使用envsubst太危险了。我的文件可能包含我不希望发生替换的地方的美元符号,如果没有定义相应的环境变量,envsubst将只用空字符串替换它们。不酷。