誰かがこのスクリプトの理由を説明できますか?
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
合計を印刷します。合計と合計の分散は保証されず、システム、シェル、および呼び出しによって異なる場合があります。このような簡単な例を使用すると、負荷の低いシステムで再現可能な結果を見ることができますが、これは信頼できるものではありません。three
four
one
two
three
four
echo one && (echo two &) echo three && echo four
解析を変更しました。ここでは、コマンドのみがecho two
バックグラウンドで実行されます。これはone
最初に出力され、beforeと同様にthree
常にbeforeになりますが、four
場所はtwo
afterのどこにでも配置できますone
。
シェルは、デフォルトのシェルプロセスで開始された場合にのみバックグラウンドプロセスのメッセージを印刷し、サブシェルで起動された場合にはそのメッセージを印刷しません。括弧はサブシェルを生成するので、シェルは(echo two &)
メッセージを出力しません。これによりバックグラウンドプロセスが作成されますが、バックグラウンドは生成されません。働く。
echo one && (sleep 2 && echo two &) echo three && echo four
このコードでは、バックグラウンドジョブは出力する前に2秒間休止状態になりますtwo
。これにより、two
後に出力がある可能性が非常に高くなります(実際には保証されません)。three
four