结合使用 envsubst 和 tee 随机生成一个空文件

Usage of envsubst combined with tee randomly results in an empty file

我想了解一个简单脚本中发生的事情,它似乎会产生随机结果。

我想做什么:


会发生什么:


如何重现问题:

FROM debian:stretch

RUN apt-get update -qy
RUN apt-get install -qy gettext

COPY main-script /main-script
RUN chmod +x /main-script

ENTRYPOINT [ "/main-script" ]
#!/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!

管道是异步的,您引入了竞争条件。您无法预测 envsubst 是在 tee 截断之前还是之后从 $FILE 读取。

正确的做法是将修改写入一个临时文件,然后成功后用临时文件替换原来的。

tmp=$(mktemp)
envsubst < "$FILE" > "$tmp" &&  mv "$tmp" "$FILE"