私はこれをたくさん見ていますdocker-entrypoint.sh
スクリプトは最近、オンラインで説明を見つけることができません。私の最初の考えは、それはシグナリングと関係があるということですが、それはかなりワイルドな推測です。
"$@"
ビットは、位置のパラメーター(通常はコマンドライン引数)のリストに展開され、Wordの分割とファイル名の生成(「グロビング」)を回避するために個別に引用されます。
exec
は、現在のプロセスを、引数を実行した結果のプロセスに置き換えます。
要するに、 exec "$@"
は、現在のプロセスがそれによって置き換えられるように、コマンドラインパラメータによって指定されたコマンドを実行します(exec
がコマンドを実行できる場合)。
"$@"
Bourneのようなシェルでは、リストコンテキストでは、個別の引数としてすべての定位置パラメーターに展開されます。
スクリプトでは、最初、定位置パラメーターはスクリプト自体が受け取った引数です。
exec
は、シェルと同じプロセスでコマンドを実行するためのものです。スクリプトが実行する最後のコマンドです。その後、プロセスはシェル以外のコマンドを実行するためです。
したがって、スクリプトが
#! /bin/sh -
exec "$@"
そして、次のようなシェルコマンドラインを使用してスクリプトを呼び出します。
/path/to/your-script 'echo' "some test" 'x y'
exec
を、echo
、some test
、x y
を引数として呼び出し、echo
を実行します(ほとんどのsh
実装で) 、/bin/echo
とは対照的に、echo
Shellビルトイン)は、以前にシェルを実行していたスクリプトと同じプロセスで、some test
およびx y
を引数として使用してスクリプトを解釈します。
2つその他 回答はexec "$@"
の機能を説明しています。 Stack Overflowに関するこの回答 はDockerにとって重要である理由を説明しています。また、ご想像のとおり、それはシグナルに関係しています。
これは、信号が正しくプロキシされるためにDockerで重要です。たとえば、Redisが
exec
なしで起動された場合、docker stop
でSIGTERM
を受信せず、正常にシャットダウンする機会がありません。場合によっては、データの損失やゾンビプロセスにつながる可能性があります。子プロセスを開始する場合(つまり、
exec
を使用しない場合)、親プロセスがシグナルを適切に処理および転送する必要があります。これは、コンテナで複数のプロセスを実行するときにsupervisord
または同様のものを使用するのが最善の理由の1つです。これは、シグナルを適切に転送するためです。