web-dev-qa-db-ja.com

シェルスクリプトでのexecコマンドの用途は何ですか?

シェルスクリプティングでexecコマンドがどのように使用されているのか簡単な例で誰かが説明できますか?

226
user2400564

execname__組み込みコマンドはカーネル内の関数を反映しています。通常はCから呼び出されるexecvename__に基づいたファミリーがあります。

execname__は、現在のプロセスの現在のプログラムを置き換えます。forkname__は新しいプロセスを置き換えません。それはあなたが書くすべてのスクリプトであなたが使うものではありませんが、それは時々役に立ちます。これが私が使ったいくつかのシナリオです。

  1. ユーザーがシェルにアクセスせずに特定のアプリケーションプログラムを実行するようにします。/etc/passwdのサインインプログラムを変更することもできますが、起動ファイルから環境設定を使用したい場合があります。したがって、(say).profileでは、最後のステートメントは次のようになります。

     exec appln-program
    

    それで今戻るシェルはありません。 appln-programがクラッシュしても、エンドユーザーはそこにいないのでシェルにアクセスできません - execname__で置き換えられました。

  2. / etc/passwdのシェルとは異なるシェルを使いたいのです。愚かに見えるかもしれませんが、一部のサイトではユーザーが自分のサインインシェルを変更できないようになっています。私が知っている1つのサイトでは、誰もがcshname__で始まっていましたが、誰もが自分の.login(cshスタートアップファイル)にkshname__を呼び出すだけです。それはうまくいきましたが、それはcshname__プロセスが動いていたままにしていて、ログアウトは2段階で、混乱を招く可能性がありました。そのため、c-Shellプログラムをkornシェルに置き換えたexec kshに変更し、すべてを単純にしました(これには、kshname__がlogin-Shellではないなどの問題があります)。

  3. プロセスを節約するためだけに。 prog1 -> prog2 -> prog3 -> prog4などを呼び出して戻ってこない場合は、各呼び出しをexecにします。それはリソースを節約し(繰り返されない限り、確かにそれほど多くはありません)、シャットダウンをより簡単にします。

あなたは明らかにexecname__がどこかで使われているのを見たことがあるでしょう。

編集:私の答えは不完全であることがわかりました。 execname__やkshname__のようなシェルでの2bashname__の使用法 - ファイル記述子を開くために使用されます。ここではいくつかの例を示します。

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番号とリダイレクト記号の間にスペースを入れると、execname__は元の意味に戻ります。

  exec 3 < thisfile       # oops, overwrite the current program with command "3"

Kshではread -uまたはprint -uを、bashname__ではそれらを使用することができます、例えば:

read <&3
echo stuff >&4
257
cdarke

受け入れられた答えを初心者向けの短い短い答えで補強するために、おそらくexecは必要ありません。

まだここにいる場合は、次の説明でその理由を明らかにする必要があります。実行すると、言う、

sh -c 'command'

shインスタンスを実行してから、commandをそのshインスタンスの子として開始します。 commandが終了すると、shインスタンスも終了します。

sh -c 'exec command'

shインスタンスを実行してから、replacesその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 yoursは/etc/shellsにリストされていないため、ログインシェルとして指定することはできません。

ファイル記述子を操作するためのexecの2番目の使用法は、別のトピックです。受け入れられた答えはそれをうまくカバーしています。この自己完結型を維持するために、execの後にコマンド名ではなくリダイレ​​クトが続くものについては、マニュアルに従うだけにします。

39
tripleee