bashコマンドがわかりませんexec
。これをスクリプト内で使用して、すべての出力をファイルにリダイレクトするのを見ました(これを参照)。しかし、私はそれがどのように機能するのか、それが一般的に何をするのか理解していません。マニュアルページを読みましたが、理解できません。
exec
もっと簡単に説明できる特別な方法で使用しているので、答えを書きます。
bashコマンドがわかりませんexec
。これをスクリプト内で使用して、すべての出力をファイルにリダイレクトするのを見ました(これを参照)。しかし、私はそれがどのように機能するのか、それが一般的に何をするのか理解していません。マニュアルページを読みましたが、理解できません。
exec
もっと簡単に説明できる特別な方法で使用しているので、答えを書きます。
回答:
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
以前実行したコマンドの出力が含まれていることがわかります。
exec
また、現在のシェルプロセスをコマンドで置き換えるのに役立ちます。そのため、親は道を進み、子はpidを所有します。これはリダイレクトだけではありません。この情報を追加してください
exec nginx <various nginx arguments>
。これは、nginxがbashスクリプトのpidを引き継ぎ、nginxがスクリプトではなくコンテナのメイン実行プロセスであることを意味します。他の誰かがより具体的な理由を知っていない限り、これは単に清潔さのためだと思いますか?
gnome-terminal
、少なくとも14.04で引数を設定するラッパースクリプトがありました。そして、それが彼らの唯一の目的です、本当に-芸術と環境を設定します。別のケースは、クリーンアップするだろう-新しいものを最初のプロセスの前のインスタンスを殺すと起動
exec
の同様の例nginx
@LukeGriffithsによって与えられる例は、~/.vnc/xstartup
スクリプトvncserver
VNCサーバプロセスを設定するために使用し、次いでexec gnome-session
又はexec startkde
ようにと。
exec
コンテナ起動スクリプトの主な理由は、コンテナのENTRYPOINTであるPID 1がDockerで特別な意味を持つことです。シグナルを受信するメインプロセスであり、存在する場合はコンテナも終了します。exec
取るためだけの方法sh
コンテナの主なプロセスをコマンドのこのチェーンのうち、およびデーモンを作ります。
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
コマンドが実行されません。
/dev/null
ので、書き込みはまだ成功し、読み取りはEOFを返します。 close(2)
fdでは、読み取り/書き込みシステムコールがエラーを返しますexec 2>&-
。
exec 3</dev/null;
ls -l /proc/self/fd
fd 3は/ dev / nullで読み取り専用で開かれることに注意してください。次にexec 3<&-
、で再度閉じls -l /proc/$$/fd
ます。シェルプロセスにfd 3がなくなったことを(再び)確認できます。(exec <&-
スクリプトでstdinを閉じることは便利ですが、対話的にはログアウトになります。)
exec
1つのユースケースについてのみ語り、g_pによる他の回答が他のユースケースについて語るだけだからです。そして、この答えは、このような複雑な主題については素晴らしく簡潔で読みやすいです。
理解exec
するには、まず理解する必要がありますfork
。私はそれを短くしようとしています。
あなたが道路の分岐点に来るとき、一般に2つのオプションがあります。Linuxプログラムは、fork()
システムコールが発生すると、この分岐点に到達し
ます。
通常のプログラムは、システム上でコンパイルされた形式で存在するシステムコマンドです。そのようなプログラムが実行されると、新しいプロセスが作成されます。この子プロセスの環境は親と同じで、プロセスID番号のみが異なります。このプロシージャはforkingと呼ばれ ます。
exec
は使用されます。exec
現在実行中のプロセスの内容をプログラムバイナリからの情報で置き換えます。exec
私が投稿したリンクのように、スクリプト出力をリダイレクトできる理由を説明できますか?
では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義務付けコマンドを指定しない場合は、現在のシェルに影響を与えるの機能を。