デュアルアンパサンドリンク条件が最後のリンク条件とともにバックグラウンドで実行されるのはなぜですか?

デュアルアンパサンドリンク条件が最後のリンク条件とともにバックグラウンドで実行されるのはなぜですか?

バックグラウンドジョブを実行するには、いくつかの条件があります。

condition-command && condition-command && background-job &

問題は、次のようにジョブが実行されるまで条件をブロックしたいということです。

condition-command; condition-command; background-job &

ただし、これは条件ではなく、前のコマンドが失敗した場合にジョブを実行したくありません。

私はそれが非同期であることを知っていますが、そうではありません。次の2つのスクリプトは同じでなければなりませんが、そうではありません。

sleep 2; echo foo & sleep 1; echo bar; wait   # prints foo, then bar: correct
sleep 2 && echo foo & sleep 1; echo bar; wait # prints bar, then foo: bug

変数をテストするか、最後の変数をサブシェルに入れるとうまくいくことがわかりましたが$?(それからジョブ制御を失い、デーモンを避けたい)、bashがこれを行う理由と実行場所が何であるかを知りたいです。記録はありますか?この動作を防ぐ方法はありますか?

編集する:Chainedifは逆重なので代替として受け入れません。
編集2:サブシェルが可能であることを知っていますが、私には機能しません。結局、いくつかのコマンドを実行したいと想像してみましょうwait。ディレクトリが存在するかどうかを確認することは可能です/proc/$PIDが、複数の作業がある場合は面倒です。
編集3:主な質問は、bashがこれを行う理由とそれに関する文書はどこにありますか?どんな解決策でもないボーナスです!

答え1

背景を行全体に適用したくない場合は、次のようにしますeval

sleep 2 && eval 'sleep 10 &'

wait2番目のコマンドだけがバックグラウンドジョブであり、実行できる正しいバックグラウンドジョブになります。

答え2

編集後:質問の&&優先順位が高い&ため、全体が1つにまとめられ、背景AND listと同じ単位として使用されます。バラよりコマンドリストマニュアルにはあま​​り明確ではありません。

元のコードに対する最小限の変更は次のとおりです。

if condition-command && condition-command; then background-job & fi

(それはい1つifですが接続されていません)。


ただ

condition-command && condition-command && (background-job &)

これで問題が解決します。

答え3

[これは本質的にjimmijのコメントが答えに変わったことです。 ]

これにより、以前のようにサブシェルを作成せ{ }ずに、通常の演算子の優先順位を上書きできます。( )したがって、以下を使用してください。

condition-command && condition-command && { background-job & }

sleep/例にecho似ています:

sleep 2 && { echo foo & }; sleep 1; echo bar; wait # prints foo, then bar: correct

{and は and などのメタ}文字ではなくシェルキーワードなので、コマンド間にスペースが(必要 (コマンド名の一部とみなされない)、記号のような、または前にコマンド終了が必要です (したがって考慮されません)。)もう一つの主張だけである)。また、その後に他のコマンドがある場合は、その間にセミコロン(または他のコマンド区切り文字)を使用する必要があります。{&;}}

関連情報