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

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

私は最近多くのスクリプトでこれを見ましたが、docker-entrypoint.shオンラインで説明が見つかりませんでした。私の最初の考えは、これが信号に関連しているということでしたが、それはかなりとんでもない推測でした。

答え1

この"$@"ビットは、単語の区切りやファイル名の生成(「ワイルドカード」)を防ぐために、個別に引用された場所引数のリスト(通常はコマンドライン引数)に展開されます。

exec現在のプロセスをその引数を実行して生成されたプロセスに置き換えます。

つまり、exec "$@"コマンドライン引数によって提供されたコマンドは、現在のプロセスが置き換えられた状態で実行されます(execコマンドが実行できる場合)。

答え2

二つ その他答えは何を説明しますexec "$@"スタックオーバーフローに対するこの回答Dockerにとって重要な理由を説明し、推測したように信号に関連しています。

これは、Dockerでシグナルを適切にプロキシするために非常に重要です。たとえば、Redisがこの機能なしで起動するとオンになり、exec完全にシャットダウンする機会はありません。場合によっては、データの損失やゾンビプロセスが発生する可能性があります。SIGTERMdocker stop

子プロセスを開始すると(つまり、使用しないexec)、親プロセスはシグナルを適切に処理して転送する責任があります。supervisordコンテナ内で複数のプロセスを実行する場合、これが最もよく使用されるか、または類似の理由の1つは、シグナルを適切に渡すことです。

答え3

"$@"Bourneのようなシェルでは、リストコンテキストはすべての位置引数を別々の引数に拡張します。

スクリプトの最初の場所パラメータは、スクリプト自体から受け取ったパラメータです。

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

したがって、スクリプト

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

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

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

これは、以前にシェルが実行されたのと同じプロセスで実行される引数として、および引数としてexec呼び出さechoれます(ほとんどの実装では組み込みシェルではなく)、スクリプトは引数として解釈されます。some testx yechosh/bin/echoechosome testx y

関連情報