docker-compose
を使用してテスト環境を起動するスクリプトがあります。このスクリプトは、stdout上の多くのdockerコンテナーの混合stdoutを以下にパイプします。
# This is part of a larger script with some setup and teardown.
$ docker-compose up --build | less +F -r
less
は、ここで望ましくない動作を示しています。 Ctrl+C、docker-compose
はそれを受け取り、それ自体をシャットダウンします。望ましい動作は、less
の次の(+F
)機能を中断することだけです(大きなログなどを表示する場合と同様)。
最適な場合に達成したいこと:最初の Ctrl+C 2番目にテスト環境全体を終了します Ctrl+C。
私は少しいじって、次のことを試しました:
trap 'do_exit' SIGINT
を登録します。 docker-compose
ただし、まだ終了している Ctrl+C。trap '' SIGINT
を使用して、SIGNTを完全にキャッチします。 docker-compose
しかし、それでも Ctrl+C 薄い空気から。別の観察:
これはzsh
で機能します:(trap '' SIGINT && docker-compose up --build | less +F -r)
(SIGINTにはまったく反応しません)同じ行はbashで異なる動作をし、SIGINTによって強制終了されます。
参考のために、完全な(バギー)スクリプトを次に示します。
#!/usr/bin/env bash
service_name=xxx
for dir in ../1 ../2 ../3; do
if [ ! -d "$dir" ]; then
echo "docker compose requires $dir, please check $dir do exist in the same folder level"
exit 0
fi
done
docker-compose up --build | less +F -r
if [ ! $? -eq 0 ]; then
echo "Couldn't start service or Control-C was pressed"
echo "cleaning up"
docker-compose down
exit $?
fi
docker-compose rm --all --force
これに関する解決策や経験はありますか?
-
編集:私もここで解決策を試しましたが成功しませんでした:
私はこれを読んだ後にそれを理解しました:
解決策は、スクリプトの開始時にset -m
を実行することです。これにより、bashはプロセスごとに新しいプロセスグループを作成し、スクリプト内のすべてのプロセスにSIGINTが送信されることはありません。
参考までに、修正されたスクリプトは次のようになります。
#!/usr/bin/env bash
set -m
set -e
service_name=xxx
for dir in ../1 ../2 ../3; do
if [ ! -d "$dir" ]; then
echo "docker compose requires $dir, please check $dir do exist in the same folder level"
exit 0
fi
done
TEMP_LOG_FILE=$(mktemp --suffix '-dev-env-log')
(trap '' SIGINT && docker-compose up --build > ${TEMP_LOG_FILE}) &
less +F -r ${TEMP_LOG_FILE}
rm ${TEMP_LOG_FILE}
echo "Less was quit, stopping containers..."
if [ ! $? -eq 0 ]; then
echo "could not start service or Control-C was pressed"
echo "cleaning up"
docker-compose down
exit $?
fi
docker-compose down
docker-compose rm --all --force