「exec」コマンドは何をしますか?


107

bashコマンドがわかりませんexec。これをスクリプト内で使用して、すべての出力をファイルにリダイレクトするのを見ました(これを参照)。しかし、私はそれがどのように機能するのか、それが一般的に何をするのか理解していません。マニュアルページを読みましたが、理解できません。


あなたはプロセスが何であるかについてよく知っていますか?
fkraiem 14

1
@fkraiemどういう意味ですか?
ベッコ14

申し訳ありませんが、「何」を意味していました。:pしかし、答えはノーのようです。
fkraiem 14

しかし、実際には、スクリプトはexecもっと簡単に説明できる特別な方法で使用しているので、答えを書きます。
fkraiem 14

回答:


88

man bash 言う:

exec [-cl] [-a name] [command [arguments]]
      If command is specified, it replaces the shell.  No new  process
      is  created.  The arguments become the arguments to command.  If
      the -l option is supplied,  the  shell  places  a  dash  at  the
      beginning  of  the  zeroth  argument passed to command.  This is
      what login(1) does.  The -c option causes command to be executed
      with  an empty environment.  If -a is supplied, the shell passes
      name as the zeroth argument to the executed command.  If command
      cannot  be  executed  for  some  reason, a non-interactive shell
      exits, unless the execfail shell option  is  enabled.   In  that
      case,  it returns failure.  An interactive shell returns failure
      if the file cannot be executed.  If command  is  not  specified,
      any  redirections  take  effect  in  the  current shell, and the
      return status is 0.  If there is a redirection error, the return
      status is 1.

最後の2行は重要です:execコマンドなしで単独で実行すると、単にリダイレクトが現在のシェルに適用されます。を実行するcommand > fileと、端末の代わりにの出力commandが書き込まれることをご存じでしょうfile(これはリダイレクトと呼ばれます)。exec > file代わりに実行すると、リダイレクトはシェル全体に適用されfileます。シェルによって生成された出力は、ターミナルではなく書き込まれます。ここに例

bash-3.2$ bash
bash-3.2$ exec > file
bash-3.2$ date
bash-3.2$ exit
bash-3.2$ cat file
Thu 18 Sep 2014 23:56:25 CEST

最初に新しいbashシェルを開始します。次に、この新しいシェルでを実行してexec > file、すべての出力がにリダイレクトされるようにしfileます。実際、その後は実行しますdateが、出力はにリダイレクトされるため、出力は得られませんfile。次に、シェルを終了し(リダイレクトが適用されなくなるように)、file実際にdate以前実行したコマンドの出力が含まれていることがわかります。


42
これは部分的な説明にすぎません。execまた、現在のシェルプロセスをコマンドで置き換えるのに役立ちます。そのため、親は道を進み、子はpidを所有します。これはリダイレクトだけではありません。この情報を追加してください
Sergiy Kolodyazhnyy

3
@SergiyKolodyazhnyyのコメントをフォローアップすると、このページにたどり着いたばかりの例はdocker-entrypoint.shで、nginx configでさまざまなアクションを実行した後、スクリプトの最終行がになりますexec nginx <various nginx arguments>。これは、nginxがbashスクリプトのpidを引き継ぎ、nginxがスクリプトではなくコンテナのメイン実行プロセスであることを意味します。他の誰かがより具体的な理由を知っていない限り、これは単に清潔さのためだと思いますか?
ルークグリフィス

1
@Lukeこれは「ラッパースクリプト」と呼ばれます。その例としてはgnome-terminal、少なくとも14.04で引数を設定するラッパースクリプトがありました。そして、それが彼らの唯一の目的です、本当に-芸術と環境を設定します。別のケースは、クリーンアップするだろう-新しいものを最初のプロセスの前のインスタンスを殺すと起動
Sergiy Kolodyazhnyy

execの同様の例nginx@LukeGriffithsによって与えられる例は、~/.vnc/xstartupスクリプトvncserverVNCサーバプロセスを設定するために使用し、次いでexec gnome-session又はexec startkdeようにと。
トレバーボイドスミス

@LukeGriffiths、execコンテナ起動スクリプトの主な理由は、コンテナのENTRYPOINTであるPID 1がDockerで特別な意味を持つことです。シグナルを受信するメインプロセスであり、存在する場合はコンテナも終了します。exec取るためだけの方法shコンテナの主なプロセスをコマンドのこのチェーンのうち、およびデーモンを作ります。
kkm

45

exec は、少なくとも1つの引数が使用されるか、引数がまったく使用されないかに応じて、2つの非常に異なる動作を持つコマンドです。

  • 少なくとも1つの引数が渡された場合、最初の引数はコマンド名として使用されexec、残りの引数があればそのコマンドに渡し、リダイレクトがあればそれを管理するコマンドとして実行しようとします。

  • 最初の引数として渡されたコマンドが存在しない場合、execコマンドだけでなく現在のシェルがエラーで終了します。

  • コマンドが存在し、実行可能である場合、現在のシェルを置き換えます。つまりexec、スクリプトに表示された場合、exec呼び出しに続く命令は実行されませんexecサブシェル内にある場合を除く)。exec戻ることはありません。「EXIT」などのシェルトラップもトリガーされません。

  • 引数が渡されない場合exec、現在のシェルファイル記述子を再定義するためにのみ使用されます。exec前の場合とは異なり、シェルはの後に続きますが、標準入力、出力、エラー、またはリダイレクトされたファイル記述子が有効になります。

  • リダイレクトの一部がを使用する場合/dev/null、そこからの入力はEOFを返し、そこへの出力はすべて破棄されます。

  • -ソースまたは宛先として使用することにより、ファイル記述子を閉じることができますexec <&-。その後の読み取りまたは書き込みは失敗します。

以下に2つの例を示します。

echo foo > /tmp/bar
exec < /tmp/bar # exec has no arguments, will only affect current shell descriptors, here stdin
cat # simple command that read stdin and write it to stdout

このスクリプトは、通常はfooを含む/ tmp / barファイルから入力を取得するため、ユーザー入力を待つ代わりに、catコマンドとして「foo」を出力します。

echo foo > /tmp/bar
exec wc -c < /tmp/bar # exec has two arguments, the control flow will switch to the wc command
cat

このスクリプトは4(/ tmp / barのバイト数)を表示し、すぐに終了します。catコマンドが実行されません。


4
`一部の古い投稿は決して古くなることはありません... +1。
Cbhihe

3
リダイレクトの一部が/ dev / nullを使用する場合、関連するファイル記述子は閉じられます。 いいえ、それは本当に/へのリダイレクトを行う/dev/nullので、書き込みはまだ成功し、読み取りはEOFを返します。 close(2)fdでは、読み取り/書き込みシステムコールがエラーを返しますexec 2>&-
ピーターコーデス

2
自分で試してください::exec 3</dev/null; ls -l /proc/self/fdfd 3は/ dev / nullで読み取り専用で開かれることに注意してください。次にexec 3<&-、で再度閉じls -l /proc/$$/fdます。シェルプロセスにfd 3がなくなったことを(再び)確認できます。(exec <&-スクリプトでstdinを閉じることは便利ですが、対話的にはログアウトになります。)
Peter Cordes

@PeterCordesあなたは絶対に正しいです。回答が更新されました。ありがとう!
jlliagre

1
この答えは素晴らしいです。なぜなら、これは、現在最も多く支持されている回答の2つのユースケースがexec1つのユースケースについてのみ語り、g_pによる他の回答が他のユースケースについて語るだけだからです。そして、この答えは、このような複雑な主題については素晴らしく簡潔で読みやすいです。
トレバーボイドスミス

33

理解execするには、まず理解する必要がありますfork。私はそれを短くしようとしています。

  • あなたが道路の分岐点に来るとき、一般に2つのオプションがあります。Linuxプログラムは、fork()システムコールが発生すると、この分岐点に到達し ます。

  • 通常のプログラムは、システム上でコンパイルされた形式で存在するシステムコマンドです。そのようなプログラムが実行されると、新しいプロセスが作成されます。この子プロセスの環境は親と同じで、プロセスID番号のみが異なります。このプロシージャはforkingと呼ばれ ます。

  • フォークは、既存のプロセスが新しいプロセスを開始する方法を提供します。ただし、子プロセスが親プロセスと同じプログラムの一部ではない場合があります。この場合execは使用されます。exec 現在実行中のプロセスの内容をプログラムバイナリからの情報で置き換えます。
  • 分岐プロセスの後、子プロセスのアドレス空間は新しいプロセスデータで上書きされます。これは、システムへのexec呼び出しを介して行われます。

3
exec私が投稿したリンクのように、スクリプト出力をリダイレクトできる理由を説明できますか?
ベッコ14

1
「しかし、子プロセスが親プロセスと同じプログラムの一部ではない状況があるかもしれません」
-cdosborn

6

ではbash、あなたがしなければhelp exec

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

    Options:
      -a name   pass NAME as the zeroth argument to COMMAND
      -c        execute COMMAND with an empty environment
      -l        place a dash in the zeroth argument to COMMAND

    If the command cannot be executed, a non-interactive shell exits, unless
    the shell option `execfail' is set.

    Exit Status:
    Returns success unless COMMAND is not found or a redirection error occurs.

関連ビット:

If COMMAND is not specified, any redirections take effect in the current shell.

execあるシェルの組み込みのシェルと同等である、execの家族システムが呼び出すことG_Pは話す(およびそのマニュアルページあなたが読んでいるように見えます)。それはちょうど持っているPOSIX義務付けコマンドを指定しない場合は、現在のシェルに影響を与えるの機能を。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.