簡単に言えば、次のラッパースクリプトの例を見ました。
#!/bin/bash
myprog=sleep
echo "This is the wrapper script, it will exec "$myprog""
exec "$myprog" "$@"
上記のようにexec
ほぼ直ちに動作します$myprog
。以下を使用せずに同じ目標を達成できますexec
。
#!/bin/bash
myprog=sleep
echo "This is the wrapper script, it will exec "$myprog""
"$myprog" "$@"
最後の例では、新しい bash インスタンスが起動され、$myprog
その bash インスタンスの子プロセスで始まります。
最初のアプローチの利点は何ですか?
答え1
使用すると、exec
ラッパーがより透明になります。つまり、スクリプトを呼び出すユーザーまたはアプリケーションが「実際の」プログラムを実行するリレーであることを知る必要が少なくなります。
特に、呼び出し側がプログラムを終了したい場合は、起動したばかりのプロセスのみを終了します。ラッパースクリプトが子プロセスを実行している場合、呼び出し側はラッパーの子プロセスを見つけて終了する必要があることに注意してください。ラッパースクリプトは、特定の信号を転送するためにトラップを設定できますが、取得できないSIGSTOPまたはSIGKILLでは機能しません。
この呼び出しはexec
、追加のシェルを維持する必要がなく、何もしないため、一部のメモリ(およびPIDなどの他のリソース)を節約します。
複数のラッパーがある場合、問題は増加します(終了する正しいプロセスを見つけるのが難しい、メモリオーバーヘッドなど)。
一部のシェル(Kornシェルなど)は、コマンドが最後でアクティブなトラップを持たない時期を自動的に検出して暗黙的に配置しますが、すべてのシェルがこれを行うわけではありませんexec
(例:bashではありません)。
答え2
重複したアイテムはありません...参照FreeBSDマニュアル、これは十分な理由を提供します。
これ
exec
ステートメントはシェルプロセスを指定されたプログラムに置き換えます。もしexec
省略すると、プログラムの実行中にシェルプロセスがメモリに残ります。無駄に消費されたシステムリソース。
これが本質的にずっと前に(ポーターによって)私に説明されており、よく知られている理由です。