Pourquoi les doubles états d'esperluette et d'enstringment fonctionnent-ils en arrière-plan set le dernier?

J'ai quelques conditions pour un travail de fond à exécuter:

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

Le problème est: je veux que les conditions bloquent jusqu'à ce que le travail fonctionne, comme si j'avais couru:

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

Mais ce n'est pas une condition, si la command précédente échoue, je ne veux pas que le travail s'exécute.

J'ai réalisé qu'il était asynchronous, mais il ne devrait pas, dans mon esprit, que les deux scripts suivants soient identiques, mais ils ne le sont pas:

 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 

Je sais si je teste $? variable cela fonctionnerait, ou si je mettais le dernier dans un sous-shell (mais alors je perdrais les commands de travail, je veux éviter les démons), mais je veux savoir pourquoi bash le fait de cette façon, où est-il documenté? Y a-t-il un moyen d'empêcher ce comportement?

Edit: enchaîné if s est dégoûtant, c'est pourquoi je ne l'accepterai pas comme une alternative.
Edit 2: Je sais qu'un sous-shell est possible, mais ça ne marchera pas pour moi, imaginons que je veux lancer un tas de commands puis wait à la fin. Il sera possible si je vérifie l'existence du /proc/$PID , mais ce serait une douleur dans le cou s'il y a plusieurs tâches.
Edit 3: La question principale est de savoir pourquoi bash le fait, où est-il documenté? Que ce soit ou non une solution est un bonus!

Si vous ne souhaitez pas que l'arrière-plan s'applique à toute la ligne, utilisez eval :

 sleep 2 && eval 'sleep 10 &' 

Maintenant, seule la deuxième command sera un travail en arrière-plan, et ce sera un bon travail en arrière-plan que vous pouvez wait .

Après votre modification, le problème est que && a une priorité supérieure à & , donc l'set se lie dans une AND list , et obtient un arrière-plan en tant qu'unité. Voir la list des commands dans le manuel, bien que ce ne soit pas très clair.

Le plus petit changement à votre code d'origine qui fonctionnerait serait

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

(c'est un if , mais pas un enchaîné).


Juste

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

devrait faire l'affaire.