web-dev-qa-db-ja.com

`exec" $ @ "`は何をしますか?

私はこれをたくさん見ていますdocker-entrypoint.shスクリプトは最近、オンラインで説明を見つけることができません。私の最初の考えは、それはシグナリングと関係があるということですが、それはかなりワイルドな推測です。

5

"$@"ビットは、位置のパラメーター(通常はコマンドライン引数)のリストに展開され、Wordの分割とファイル名の生成(「グロビング」)を回避するために個別に引用されます。

execは、現在のプロセスを、引数を実行した結果のプロセスに置き換えます。

要するに、 exec "$@"は、現在のプロセスがそれによって置き換えられるように、コマンドラインパラメータによって指定されたコマンドを実行します(execがコマンドを実行できる場合)。

4
Kusalananda

"$@" Bourneのようなシェルでは、リストコンテキストでは、個別の引数としてすべての定位置パラメーターに展開されます。

スクリプトでは、最初、定位置パラメーターはスクリプト自体が受け取った引数です。

execは、シェルと同じプロセスでコマンドを実行するためのものです。スクリプトが実行する最後のコマンドです。その後、プロセスはシェル以外のコマンドを実行するためです。

したがって、スクリプトが

#! /bin/sh -
exec "$@"

そして、次のようなシェルコマンドラインを使用してスクリプトを呼び出します。

/path/to/your-script 'echo' "some  test" 'x y'

execを、echosome testx yを引数として呼び出し、echoを実行します(ほとんどのsh実装で) 、/bin/echoとは対照的に、echo Shellビルトイン)は、以前にシェルを実行していたスクリプトと同じプロセスで、some testおよびx yを引数として使用してスクリプトを解釈します。

4

2つその他 回答はexec "$@"の機能を説明しています。 Stack Overflowに関するこの回答 はDockerにとって重要である理由を説明しています。また、ご想像のとおり、それはシグナルに関係しています。

これは、信号が正しくプロキシされるためにDockerで重要です。たとえば、Redisがexecなしで起動された場合、docker stopSIGTERMを受信せず、正常にシャットダウンする機会がありません。場合によっては、データの損失やゾンビプロセスにつながる可能性があります。

子プロセスを開始する場合(つまり、execを使用しない場合)、親プロセスがシグナルを適切に処理および転送する必要があります。これは、コンテナで複数のプロセスを実行するときにsupervisordまたは同様のものを使用するのが最善の理由の1つです。これは、シグナルを適切に転送するためです。

4
Stephen Kitt