サブシェルで実行するものとcoprocコマンドで&を使用することの違いは何ですか?

サブシェルで実行するものとcoprocコマンドで&を使用することの違いは何ですか?

私は最近Linuxのサブシェルについて読んだ。使用される例はスリープ10です。

(sleep 10)  -  subshell
sleep 10&   - background process
coproc sleep 10  

記録上の最初のコマンドはサブシェルで実行されます。 2番目は、サブシェルを含まないバックグラウンドプロセスです。 3番目は2つの組み合わせです。を使用してテストしましたが ps -ef、これらのコマンドはすべてサブシェルの作成を示しています。 &とサブシェルを使用するバックグラウンドプロセスの間に違いはありますか? coprocも同じことをしているようです。私は完全に混乱しています。このトピックの明確な説明をいただきありがとうございます。

答え1

sleepシェルの組み込みではなくシェルで実行されるため、いずれの場合も別々のプロセスで実行する必要があります(これは組み込みksh93または組み込みmksh内でsleep異なります)。

(sleep 10)気づいたサブシェル環境。シェル環境(エイリアス、変数、関数、umask、作業ディレクトリ、リダイレクト...)への修正は、シェル環境にのみ影響し、返されると(...)失われるという概念です。(...)

ほとんどのシェルは子プロセスをフォークしてこれを行います。すべてのシェルがこれを行うわけではありません。ksh93代わりに、この場合はフォークせずにスタックに以前の設定を保存し、終了時に復元します。

多くのシェルで最適化を行うと、サブシェルの最後のコマンドが外部コマンドであり(sleepあなたの場合のように)設定がない場合、trapシェルはプロセスを実行するためにフォークせずにサブシェルから直接実行します。とにかく後で必要ないので処理してください。

シェルの場合、bashこれはそのコマンドがサブシェルの唯一のコマンドである場合にのみ発生します(これもあなたの場合です)。

sleep 10&またcoproc sleep 10、サブシェル環境を起動しますが、これらの場合は並列に実行される2つのスレッドがあるため、サブプロセスを使用して実行する必要があります。 2つの違いは、このcoproc場合、サブシェルのstdinとstdoutが親シェルと対話するために2つのパイプに接続されていることです。

この(...)例と同様に、サブシェルが 1 つのコマンドのみで構成されている場合、そのコマンドはシェルプロセスで直接実行されます。

違いをよりよく確認するには、次のように複数のコマンドを実行するサブシェルを実行できます。

{ ps; echo done; } # no subshell
(ps; echo done)
{ ps; echo done; } &
coproc { ps; echo done; }

関連情報