簡単な例を使用して、シェルスクリプトでの exec コマンドの使用法を説明できる人はいますか?
2 に答える
組み込みコマンドは、カーネル内の関数をミラーリングします。通常は C から呼び出される にexec
基づくファミリがあります。execve
exec
fork
新しいプロセスを作成せずに、現在のプロセスの現在のプログラムを置き換えます。これは、作成するすべてのスクリプトで使用するものではありませんが、場合によっては便利です。私が使用したいくつかのシナリオを次に示します。
ユーザーがシェルにアクセスせずに特定のアプリケーション プログラムを実行できるようにします。/etc/passwd のサインイン プログラムを変更することもできますが、環境設定をスタートアップ ファイルから使用する必要があるかもしれません。したがって、 (say)
.profile
の最後のステートメントは次のようになります。exec appln-program
そのため、戻るシェルはありません。クラッシュした場合でも
appln-program
、シェルが存在しないため、エンドユーザーはシェルにアクセスできません。シェルがexec
置き換えられます。/etc/passwd にあるものとは異なるシェルを使用したいと考えています。ばかげているように思えるかもしれませんが、サイトによっては、ユーザーがサインイン シェルを変更することを許可していません。私が知っている 1 つのサイトでは
csh
、誰も.login
がksh
. それが機能している間、それは迷子のcsh
プロセスを実行したままにし、ログアウトは混乱を招く可能性のある2段階でした. そこでexec ksh
、c-shell プログラムを korn シェルに置き換えただけのものに変更し、すべてを単純化しました (これには、ログインシェルではないという事実など、他の問題がありksh
ます)。プロセスを節約するためだけに。etc.を呼び出し
prog1 -> prog2 -> prog3 -> prog4
て戻らない場合は、各呼び出しを exec にします。リソースを節約し (確かに、繰り返さない限りそれほど多くはありません)、シャットダウンをより簡単にします。
おそらくどこかで使用されているのを見たことがexec
あるでしょう。おそらく、バグのあるコードを示した場合、その使用を正当化できるでしょう。
編集:上記の私の答えが不完全であることに気付きました。ファイル記述子を開くために使用される -のようなシェルでの2 つの使用法があります。ここではいくつかの例を示します。exec
ksh
bash
exec 3< thisfile # open "thisfile" for reading on file descriptor 3
exec 4> thatfile # open "thatfile" for writing on file descriptor 4
exec 8<> tother # open "tother" for reading and writing on fd 8
exec 6>> other # open "other" for appending on file descriptor 6
exec 5<&0 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4 # copy write file descriptor 4 onto 7
exec 3<&- # close the read file descriptor 3
exec 6>&- # close the write file descriptor 6
ここでは間隔が非常に重要であることに注意してください。fd 番号とリダイレクト記号の間にスペースをexec
入れると、元の意味に戻ります。
exec 3 < thisfile # oops, overwrite the current program with command "3"
これらを使用する方法はいくつかあります。たとえば、 on ksh useread -u
またはprint -u
onです。bash
read <&3
echo stuff >&4
受け入れられた回答を初心者向けの簡単な短い回答で補強するだけなら、おそらく必要ありませんexec
。
まだここにいる場合は、次の説明で理由が明らかになるはずです。走るときはこう言います。
sh -c 'command'
インスタンスを実行してから、そのインスタンスの子としてsh
開始します。終了すると、インスタンスも終了します。command
sh
command
sh
sh -c 'exec command'
sh
インスタンスを実行し、そのインスタンスをバイナリに置き換えて、代わりにそれを実行します。sh
command
もちろん、これらは両方とも、この限られたコンテキストでは役に立ちません。あなたは単に欲しい
command
シェルに構成ファイルを読み取らせたり、実行の準備として何らかの方法で環境をセットアップさせたりする必要がある、いくつかの特殊な状況がありますcommand
。これは、ほぼ唯一のexec command
便利な状況です。
#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command
これは、必要なものが含まれるように環境を準備するためにいくつかのことを行います。それが完了すると、sh
インスタンスは不要になるため、インスタンスを子プロセスとして実行して待機し、終了したらすぐに終了するのではなく、単純にsh
インスタンスをプロセスに置き換えるのが (マイナーな) 最適化です。command
sh
同様に、シェル スクリプトの最後に重いコマンドを実行するためにできるだけ多くのリソースを解放したい場合は、exec
そのコマンドを最適化することをお勧めします。
何かを実行するsh
必要があるが、本当に何か他のものを実行したい場合exec something else
は、もちろん、望ましくないインスタンスを置き換えるための回避策sh
です (たとえば、gosh
代わりに自分の spiffy を本当に実行したいが、自分の spiffysh
がリストに/etc/shells
ない場合など)。ログインシェルとして指定しないでください)。
ファイル記述子を操作するための の 2 番目の使用法exec
は、別のトピックです。受け入れられた答えはそれをうまくカバーしています。exec
これを自己完結型に保つために、コマンド名の代わりにリダイレクトが続く場合は、マニュアルに従ってください。