web-dev-qa-db-ja.com

Dockerエントリポイントスクリプトに対してset -eおよびexec "$ @"は何をしますか?

Dockerの多くのentrypoint.shスクリプトが次のようなことをしていることに気付きました。

#!/bin/bash
set -e

... code ...

exec "$@"

set -eおよびexec "$@"とは何ですか?

61
Nathan

基本的に、追加のコマンドライン引数をすべて受け取り、コマンドとして実行します。意図は基本的に「この.shスクリプトですべてを実行してから、同じシェルでユーザーがコマンドラインで渡すコマンドを実行する」ことです。

見る:

51
Matthew

set -e-コマンドが失敗した場合に終了スクリプト(ゼロ以外の値)

exec "$@"-入力変数をリダイレクトします。詳細を参照してください here

23
agilob

set -eは、実行中のコマンドがゼロ以外の終了コードで終了した場合、すぐに終了するようにシェルオプションを設定します。スクリプトは、失敗したコマンドの終了コードを返します。 bashのmanページから:

set -e:

パイプライン(単一の単純なコマンドで構成されている場合もある)、リスト、または複合コマンド(上記のShell GRAMMARを参照)がゼロ以外のステータスで終了した場合、すぐに終了します。失敗するコマンドがwhileまたはuntilキーワードの直後のコマンドリストの一部である場合、予約語ifまたはElifの後に続くテストの一部、&&または||で実行されるコマンドの一部である場合、シェルは終了しません。最後の&&または||に続くコマンド、パイプライン内の最後のコマンド以外のコマンド、またはコマンドの戻り値が!で反転されている場合を除きます。 -eが無視されている間にコマンドが失敗したためにサブシェル以外の複合コマンドがゼロ以外のステータスを返す場合、シェルは終了しません。 ERRのトラップは、設定されている場合、シェルが終了する前に実行されます。このオプションは、シェル環境と各サブシェル環境に個別に適用され(上記の「コマンド実行環境」を参照)、サブシェル内のすべてのコマンドを実行する前にサブシェルを終了させる場合があります。

複合コマンドまたはシェル関数が-eが無視されるコンテキストで実行される場合、複合コマンドまたは関数本体内で実行されるコマンドは、-eが設定され、コマンドがaを返す場合でも、-e設定の影響を受けません。障害ステータス。複合コマンドまたはシェル関数が-eが無視されるコンテキストで実行中に-eを設定した場合、その設定は複合コマンドまたは関数呼び出しを含むコマンドが完了するまで効果がありません。


exec "$@"は通常、エントリポイントをパススルーにして、その後dockerコマンドを実行するために使用されます。現在実行中のシェルを、"$@"が指しているコマンドに置き換えます。デフォルトでは、その変数はコマンドライン引数を指します。

Entrypoint.shを指すエントリポイントを持つイメージがあり、コンテナをdocker run my_image server startとして実行すると、コンテナでentrypoint.sh server startを実行することに変換されます。 exec行entrypoint.shで、pid 1として実行されているシェルは、コマンドserver startに置き換えられます。

これは信号処理にとって重要です。 execを使用しないと、上記の例のserver startは別のpidとして実行され、終了後、シェルスクリプトに戻ります。 pid 1のシェルでは、SIGTERMはデフォルトで無視されます。つまり、docker stopがコンテナに送信する正常な停止信号は、serverプロセスによって受信されることはありません。 10秒後(デフォルト)、docker stopはグレースフルシャットダウンを断念し、アプリを強制的に終了させるSIGKILLを送信しますが、潜在的なデータ損失またはネットワーク接続の終了により、アプリ開発者は彼らは信号を受信しました。また、コンテナの停止には常に10秒かかります。

shiftset --などのシェルコマンドを使用すると、"$@"の値を変更できることに注意してください。例えば。これは、CMDにdockerのシェル構文を使用した場合に表示されるコマンドから/bin/sh -c "..."を削除するスクリプトの短い部分です。

# convert `/bin/sh -c "server start"` to `server start`
if [ $# -gt 1 ] && [ x"$1" = x"/bin/sh" ] && [ x"$2" = x"-c" ]; then
  shift 2
  eval "set -- $1"
fi

....

exec "$@"
22
BMitch