277

簡単な例を使用して、シェルスクリプトでの exec コマンドの使用法を説明できる人はいますか?

4

2 に答える 2

305

組み込みコマンドは、カーネル内の関数をミラーリングします。通常は C から呼び出される にexec基づくファミリがあります。execve

execfork新しいプロセスを作成せずに、現在のプロセスの現在のプログラムを置き換えます。これは、作成するすべてのスクリプトで使用するものではありませんが、場合によっては便利です。私が使用したいくつかのシナリオを次に示します。

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

     exec appln-program
    

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

  2. /etc/passwd にあるものとは異なるシェルを使用したいと考えています。ばかげているように思えるかもしれませんが、サイトによっては、ユーザーがサインイン シェルを変更することを許可していません。私が知っている 1 つのサイトではcsh、誰も.loginksh. それが機能している間、それは迷子のcshプロセスを実行したままにし、ログアウトは混乱を招く可能性のある2段階でした. そこでexec ksh、c-shell プログラムを korn シェルに置き換えただけのものに変更し、すべてを単純化しました (これには、ログインシェルではないという事実など、他の問題がありkshます)。

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

おそらくどこかで使用されているのを見たことがexecあるでしょう。おそらく、バグのあるコードを示した場合、その使用を正当化できるでしょう。

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

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 -uonです。bash

read <&3
echo stuff >&4
于 2013-08-21T07:40:28.050 に答える
49

受け入れられた回答を初心者向けの簡単な短い回答で補強するだけなら、おそらく必要ありませんexec

まだここにいる場合は、次の説明で理由が明らかになるはずです。走るときはこう言います。

sh -c 'command'

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

sh -c 'exec command'

shインスタンスを実行し、そのインスタンスをバイナリに置き換えて、代わりにそれを実行します。shcommand

もちろん、これらは両方とも、この限られたコンテキストでは役に立ちません。あなたは単に欲しい

command

シェルに構成ファイルを読み取らせたり、実行の準備として何らかの方法で環境をセットアップさせたりする必要がある、いくつかの特殊な状況がありますcommand。これは、ほぼ唯一のexec command便利な状況です。

#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command

これは、必要なものが含まれるように環境を準備するためにいくつかのことを行います。それが完了すると、shインスタンスは不要になるため、インスタンスを子プロセスとして実行して待機し、終了したらすぐに終了するのではなく、単純にshインスタンスをプロセスに置き換えるのが (マイナーな) 最適化です。commandsh

同様に、シェル スクリプトの最後に重いコマンドを実行するためにできるだけ多くのリソースを解放したい場合は、execそのコマンドを最適化することをお勧めします。

何かを実行するsh必要があるが、本当に何か他のものを実行したい場合exec something elseは、もちろん、望ましくないインスタンスを置き換えるための回避策shです (たとえば、gosh代わりに自分の spiffy を本当に実行したいが、自分の spiffyshがリストに/etc/shellsない場合など)。ログインシェルとして指定しないでください)。

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

于 2016-07-26T05:01:42.207 に答える