そのアプリケーションビルドスクリプトをトリガーする入力ベースのbashスクリプトを作成しようとしています。入力が「all」の場合、すべてのアプリケーションが呼び出されます。ここで問題が発生します。入力が「all」の場合、app_1とapp_2のみが呼び出されます。何が問題になりますか?
if [ "${_BUILD_MODE}" = "all" ] || [ "${_BUILD_MODE}" = "app_1" ]
then
echo "BUILD_STAGE APP_1 build started"
fi
if [ "${_BUILD_MODE}" = "all" ] || [ "${_BUILD_MODE}" = "app_2" ]
then
echo "BUILD_STAGE APP_2 build started"
fi
if [ "${_BUILD_MODE}" = "all" ] || [ "${_BUILD_MODE}" = "app_3" ]
then
echo "BUILD_STAGE APP_3 build started"
fi
if [ "${_BUILD_MODE}" = "all" ] || [ "${_BUILD_MODE}" = "app_4" ]
then
echo "BUILD_STAGE APP_4 build started"
fi
if [ "${_BUILD_MODE}" = "all" ] || [ "${_BUILD_MODE}" = "app_5" ]
then
echo "BUILD_STAGE APP_5 build started"
fi
if [ "${_BUILD_MODE}" = "all" ] || [ "${_BUILD_MODE}" = "app_6" ]
then
echo "BUILD_STAGE APP_6 build started"
fi
答え1
ここで提供したサンプルコードではこれは発生しません。おそらく、これらのecho
sは実行中のより複雑なタスクのプレースホルダーにすぎず、私の考えでは、タスクは実際にapp_2
値を変更するようです$_BUILD_MODE
。
ここでは、次のことができます。
case $_BUILD_MODE in
(all | app_1) task for app_1 ;;&
(all | app_2) task for app_2 ;;&
(all | app_3) task for app_3 ;;&
...
esac
これにより、長さが短くてきれいになり、$_BUILD_MODE
最初に一度だけ逆参照されるため、この特定の問題も回避できます。
;;&
上記は bash にのみ適用されます。 zshとmkshの同等の構文はwithです;|
。 zsh、mksh、およびbashのサポート;;
(唯一の標準シェルであるBourneシェルから)および;&
(Kornシェルから)。
app_2
アクションを呼び出すexit
か、exec some-other-command
致命的なエラーが発生したり、シェルプロセスが終了する可能性があります。この問題の解決策は、サブシェルを(...)
。
bash -o xtrace
(same as)を使用してスクリプトを実行し、bash -x
何が起こっているかを確認してください。
1たとえば、組み込み機能が破損したパイプに書き込まれる場合はSIGPIPEを介して、特定のリソース制限を超えた場合はSIGXCPUを介して...
答え2
実際に質問するものではありませんが、チェーンがここにあっても、いくつかのコードを繰り返すとチェーンがぎこちないように見えます[ "${_BUILD_MODE}" = "all" ]
。
代わりに、タスクを関数に入れ、その名前で配列を作成します(テストされていません)。
app_1() {
echo "BUILD_STAGE APP_1 build... "
}
app_2() {
echo "BUILD_STAGE APP_2 build... "
}
tasks=(app_1 app_2)
for task in "${tasks[@]}"; do
if [ "${_BUILD_MODE}" = "all" ] || [ "${_BUILD_MODE}" = "$task" ]; then
"$task"
fi
done
関数名は、ここで使用されているジョブ名と同じでなければなりません_BUILD_MODE
。
ここでジョブをサブシェルにラップするなど、ジョブの実行方法を変更する必要がある場合スティーブンが提案する、またはいくつかの印刷物を追加して分離する場合は、ループ内の一点でこれを行うことができます。