コマンドを実行した後
{ sleep 5; } &
出力はps
(出力1)
PID TTY TIME CMD
972 ttys000 0:00.27 -bash
2556 ttys000 0:00.00 -bash
2557 ttys000 0:00.00 sleep 5
同時に
( sleep 5 ) &
出力ps
は(出力2)
PID TTY TIME CMD
972 ttys000 0:00.28 -bash
2566 ttys000 0:00.00 sleep 5
()
{ sleep 5; } &
その結果、サブシェル環境が発生した場合、この場合は分岐したサブプロセスが発生するため、「出力1」が予想され、現在のシェルで実行されるため「出力2」が予想されます。愚かな質問のように思えるかもしれませんが、私はこれらの行動を本当に理解していません。
私がここで何を見逃しているのでしょうか?
答え1
Bashはサブシェルの最後または唯一のコマンドを実行します。そしてexec
最適化として安全にそうできると思えば。これにより、これを明確に確認できますpstree
。
$ pstree $$
bash---pstree
$ ( pstree $$ )
bash---pstree
$ ( pstree $$ ; echo)
bash---bash---pstree
$
これは、コマンドが中間シェルなしでコマンド( sleep 5 )
としてのみ表示される理由です。sleep
上記の最後の例では、echo
シェルはpstree
完了後に強制的にアクションを実行するため、中間のケースでは実際のシェルを使用でき、結果のシェルはすぐにexec
spstree
なので、最初のケースと同じように見えます(標準です)。分岐実行)。多くのシェルがこれを行います。
一方、何もないバックグラウンドで実行するには、新しいプロセスを作成する必要があります。:基本的にこれは「背景」です。中かっこ内のコマンドする通常、現在のシェルで実行されますが、バックグラウンドで実行されている場合、これは発生しません。バックグラウンドコマンドの実行中に親シェルが実行している操作を続行するには、フルシェルを実行する新しいシェルを作成する必要があります{ ... }
。
$ { pstree $$ ; }
bash---pstree
$ { pstree $$ ; } &
bash---bash---pstree
この場合、他の後続命令があるかどうかには違いはない。Bashはこの動作を文書化します。&
:
コマンドが制御演算子 "
&
"によって終了すると、シェルはサブシェルでコマンドを非同期的に実行します。これをバックグラウンドでコマンドを実行するとします。シェルは、コマンドが完了するのを待たずに状態0(true)を返します。
また、バックグラウンドでこのようなことが起こるのを見ることができます。次の組み込みコマンドread
:
$ read &
$ pstree $$
[1] 32394
[1]+ Stopped read
$ pstree $$
bash-+-bash
`-pstree
私の殻は今二つ子:bash
実行中であり、read
このpstree
出力を印刷するコマンドです。
シェルが追加の最適化を実行し、丸括弧で囲まれたサブシェルに適用されているかのように、後から適用できることは事実ですが、そうでは{ ... }
ありません。他の一部のシェルではこれを実行できますが、クイックテストでは見つかりませんでした。これは非常にまれであり、形が異なり、いくつかの奇妙な場合があります。