バックグラウンドプロセスがシェルスクリプトの実行順序を混同する

バックグラウンドプロセスがシェルスクリプトの実行順序を混同する

誰かがこのスクリプトの理由を説明できますか?

echo one && 
echo two & 
echo three && 
echo four

私にください

[1] 3692
three
four
one
two
[1]+  Done                    echo one && echo two

当然、バックグラウンドプロセス以降のすべての内容が最初に出力され、その後、バックグラウンドプロセスの前のコード行が時系列で印刷されます。私は私が書こうとしたシナリオでそれを偶然見つけましたが、それがなぜそうなったのかわかりませんでした(ただし、後ろに少し独創性があると思いますが)。

私はかっこを使ってこれを防ぐことができることを発見しました:

echo one && 
(echo two &) 
echo three && 
echo four

与えられた

one
two
three
four

そして

echo one && 
(sleep 2 && echo two &)
echo three && 
echo four

与えられた

one
three
four
two

2行目はバックグラウンドでスタンバイ状態なので、1行目はすでに実行中に出力されます。

しかし、なぜかっこがこのような効果をもたらすのでしょうか?

追加の質問:括弧がバックグラウンドPID出力を妨げるのはなぜですか?

ベストアンサー1

echo one && 
echo two & 
echo three && 
echo four

覚えておいてください。これは次のように解析されます。

echo one && echo two &
echo three && echo four

私はこのechoコマンドが成功したと仮定します(フルディスクのファイルにリダイレクトするなどの極端な場合にのみ失敗します)。したがって、このコードスニペットは2つのタスクを並列に実行します。 1 つは行の合計を印刷しone、もう 1 つは行のtwo合計を印刷します。合計と合計の分散は保証されず、システム、シェル、および呼び出しによって異なる場合があります。このような簡単な例を使用すると、負荷の低いシステムで再現可能な結果を​​見ることができますが、これは信頼できるものではありません。threefouronetwothreefour

echo one && 
(echo two &) 
echo three && 
echo four

解析を変更しました。ここでは、コマンドのみがecho twoバックグラウンドで実行されます。これはone最初に出力され、beforeと同様にthree常にbeforeになりますが、four場所はtwoafterのどこにでも配置できますone

シェルは、デフォルトのシェルプロセスで開始された場合にのみバックグラウンドプロセスのメッセージを印刷し、サブシェルで起動された場合にはそのメッセージを印刷しません。括弧はサブシェルを生成するので、シェルは(echo two &)メッセージを出力しません。これによりバックグラウンドプロセスが作成されますが、バックグラウンドは生成されません。働く

echo one && 
(sleep 2 && echo two &)
echo three && 
echo four

このコードでは、バックグラウンドジョブは出力する前に2秒間休止状態になりますtwo。これにより、two後に出力がある可能性が非常に高くなります(実際には保証されません)。threefour

おすすめ記事