誰でも簡単な例でシェルスクリプトでのexecコマンドの使用法を説明できますか?
誰でも簡単な例でシェルスクリプトでのexecコマンドの使用法を説明できますか?
回答:
exec
カーネル内の組み込みコマンドミラー機能に基づいて、それらの家族がありexecve
、通常はCから呼ばれ、
exec
fork
新しいプロセスを実行せずに、現在のプロセスの現在のプログラムを置き換えます。作成するすべてのスクリプトで使用するものではありませんが、場合によっては役立ちます。以下に、私が使用したいくつかのシナリオを示します。
ユーザーがシェルにアクセスせずに特定のアプリケーションプログラムを実行することを望みます。/ etc / passwdのサインインプログラムを変更することもできますが、環境設定を起動ファイルから使用したい場合があります。したがって、(たとえば).profile
では、最後のステートメントは次のようになります。
exec appln-program
ですから、戻るシェルはありません。appln-program
クラッシュしても、エンドユーザーはシェルにアクセスできません。シェルが存在しないため、exec
置き換えられました。
/ etc / passwdにあるシェルとは異なるシェルを使用したい。馬鹿げているように思われるかもしれませんが、一部のサイトでは、ユーザーがサインインシェルを変更することを許可していません。私が知っている1つのサイトでは、すべてのユーザーがで始まりcsh
、誰もが.login
(csh起動ファイル)への呼び出しを入力しましたksh
。それが機能している間、それは浮遊csh
プロセスを実行したままにし、ログアウトは混乱を招く可能性がある2つのステージでした。そこでexec ksh
、cシェルプログラムをkornシェルに置き換えたものに変更し、すべてをより単純にしました(これにksh
は、ログインシェルではないという事実など、他の問題があります)。
プロセスを保存するだけです。prog1 -> prog2 -> prog3 -> prog4
etc を呼び出して元に戻らない場合は、各呼び出しを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"
これらを使用する方法はいくつかあります。たとえば、kshでの使用、read -u
またはprint -u
での使用bash
です。
read <&3
echo stuff >&4
exec
リダイレクトに使用できると言っています:>コマンドが指定されていない場合、リダイレクトは現在のシェルで有効になり、戻りステータスは0です。リダイレクトエラーがある場合、戻りステータスは1ですが、どのようにしてexec
実際にファイル記述子を変更するのですか?この特定のコマンドがこのタスクに選択されるのはなぜですか?(値下げが今失敗している?)
exec >.\logfilename.log 2>&1
&>
はbash
拡張機能(を参照man bash
)であり、例はと同等exec >/var/log/userdata.log 2>&1
です。つまり、stdoutとstderrをそのファイルにリダイレクトします。以下のコマンドは、リセットされない限りこれらのリダイレクトを継承しますが、実行されます。
受け入れられた回答を初心者向けの簡単な短い回答で補強するために、おそらく必要ありません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
、sh
がリストされてい/etc/shells
ない場合など)ログインシェルとして指定しないでください)。
exec
ファイル記述子を操作するためのの2番目の使用法は、別のトピックです。受け入れられた答えはそれをうまくカバーしています。この自己完結型を維持するためexec
に、コマンド名の代わりにリダイレクトが続く箇所については、マニュアルを参照します。