Bashの話。
コマンドの終了ステータスを判定して何かしたい時、 下記のように書くことがよくある。
output=$(your_kool_command) if [ $? -ne 0 ]; then echo "Oops..." exit 1 fi
これ、if文の $?
に想定したコマンドの終了ステータス (この例では your_kool_command
のそれ)
が入っていることをコード的に表現 (保証) できなくて、くっそキモい。
つまり、下記のようにうっかり間に他のコマンド入れてしまうと、このコードは死ぬ。
output=$(your_kool_command 2> /var/log/your_kool_log_err.log) echo "##### error log #####" cat /var/log/your_kool_log_err.log if [ $? -ne 0 ]; then echo "Oops..." exit 1 fi
かと言って、↓みたいに一行であれこれするのはあまり好きくない。
if output=$(your_kool_command takes \ --too --many \ --many \ --many \ "args" "and" "opts" \ "to write in a line. hoge fuga piyo" \ 2> /var/log/your_kool_error_log.log); then echo "Oops..." exit 1 fi
大体下記のようにして、お茶を濁すものですが、これでも本質的なキモさは残ったまま。
output=$(your_fool_command 2> /var/log/your_fool_log_err.log) result=$? echo "##### error log #####" cat /var/log/your_fool_log_err.log if [ $result -ne 0 ]; then echo "Oops..." exit 1 fi
なんとなく海外のお兄さんが書いたDockerエントリポイント用シェルスクリプトみてたら、 この問題に対応するための、良さげなイディオムを見つけた。
そんなに美しくないけど、これなら大分、吐き気が治まるように思う。
. . . result=0 output=$("$@" --verbose --help 2>&1 > /dev/null) || result=$? if [ ! "$result" = "0" ]; then echo >&2 '[Entrypoint] ERROR: Unable to start MySQL. Please check your configuration.' . . .
出典: https://github.com/mysql/mysql-docker/blob/mysql-server/5.7/docker-entrypoint.sh#L37
そんなことより、リダイレクトの捌きかたがエロティックでよい。