Использование envsubst в сочетании с tee случайным образом приводит к пустому файлу - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь понять, что происходит в простом сценарии, который, кажется, дает случайные результаты.

Что я пытаюсь сделать:

  • Заменить переменные в предварительно существующие файлы из значений, определенных в среде.
  • Это делается внутри контейнера Docker со скриптом bash, который запускает команду:

    envsubst '$VAR1 $VAR2' < $FILE | tee $FILE


Что происходит:

  • Иногда рассматриваемый $FILE имеет содержимое перед командой, но ничего не содержит после команды.

Как воспроизведите проблему:

  • Dockerfile:
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" ]
  • Bash 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!

1 Ответ

1 голос
/ 05 марта 2020

Трубы асинхронны, и вы ввели состояние гонки. Вы не можете предсказать, будет ли envsubst считывать из $FILE до или после tee его усечения.

Правильный подход - записать изменения во временный файл, а затем заменить исходный временным файлом. после , что удалось.

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