Linux 将envsubt与tee结合使用会随机生成一个空文件
我希望了解在一个简单的脚本中发生了什么,它似乎会产生随机结果 我想做的是:Linux 将envsubt与tee结合使用会随机生成一个空文件,linux,bash,docker,tee,envsubst,Linux,Bash,Docker,Tee,Envsubst,我希望了解在一个简单的脚本中发生了什么,它似乎会产生随机结果 我想做的是: 从环境中定义的值替换预先存在的文件中的变量 这是在Docker容器中使用bash脚本完成的,该脚本运行以下命令: envsubst'$VAR1$VAR2'“$file”的命令替换原子(假设没有跨越任何文件系统边界)mv命令。还有scape命令,它允许您编写envsubs
- 从环境中定义的值替换预先存在的文件中的变量
- 这是在Docker容器中使用bash脚本完成的,该脚本运行以下命令:
envsubst'$VAR1$VAR2'<$FILE | tee$FILE
发生了什么:
- 有时所讨论的
在命令之前有内容,但在命令之后没有内容$文件
如何重现该问题:
- Dockerfile:
- Bash脚本:
管道是异步的,您已经引入了竞争条件。您无法预测
envsubt
是否在tee
截断之前或之后读取$FILE
正确的方法是将更改写入临时文件,然后在成功后用临时文件替换原始文件
tmp=$(mktemp)
envsubst < "$FILE" > "$tmp" && mv "$tmp" "$FILE"
tmp=$(mktemp)
envsubst<“$FILE”>“$tmp”和&mv“$tmp”“$FILE”
您不需要将文件读入内存来测试它是否为空<代码>如果[!-s“$FILE”];然后,一个问题是,$FILE
是指向某个文件的符号链接。这一点很好。您可以使用类似于cat“$tmp”>“$file”
的命令替换原子(假设没有跨越任何文件系统边界)mv
命令。还有scape
命令,它允许您编写envsubs<“$file”| scape“$file”
因为海绵
在读取所有输入之前不会打开文件进行写入。(我通常不会提及它,因为1)它是非标准的,2)我只是没有使用它的实际经验。)
#!/bin/bash
mkdir -p /test
export TEST1=1
export TEST2=2
export TEST3=3
for I in {1..300} ; do
echo '$TEST1 $TEST2 $TEST3' > /test/file-$I
done
for FILE in /test/file-* ; do
envsubst < $FILE | tee $FILE
done
for FILE in /test/file-* ; do
if [[ -z "$(cat $FILE)" ]]; then
echo "$FILE is empty!"
FAIL=1
fi
done
if [[ -n "$FAIL" ]]; then
exit 2
fi
...
/test/file-11 is empty!
/test/file-180 is empty!
/test/file-183 is empty!
/test/file-295 is empty!
tmp=$(mktemp)
envsubst < "$FILE" > "$tmp" && mv "$tmp" "$FILE"