processus d'entrée en arrière-plan

14

si je veux afficher "aaa" à l'écran:

(1)$: echo aaa | cat                 ... works OK
(2)$: echo aaa | ( cat )             ... works OK
(3)$: echo aaa | ( cat & )           ... NOT working
(4)$: ( echo aaa & ) | cat           ... works OK 
(5)$: echo aaa | ( cat <&0 & )       ... works ok in BASH (but not in SH)
(6)$: echo aaa | ( cat <&3 & ) 3<&0  ... works ok in BASH and SH

Conlusion de (3) et (4) -> le processus détaché a toujours une sortie connectée qui peut être contrôlée, utilisée, redirigée ..., mais pas d'entrée!

Ma question est: quelqu'un comprend-il pourquoi et comment fonctionne la ligne (5) ???

... "<& 0" est l'abréviation de "0 <& 0", pourquoi rediriger 0 vers 0 est une solution, et ce qui se passe vraiment derrière avec l'entrée du processus détaché. Les sous-coquilles ne sont pas le problème, l'utilisation d'accolades {...} au lieu de (...) donne les mêmes résultats.

... et question2: existe-t-il une meilleure solution pour "donner une entrée au processus détaché" que la ligne (6).

Asain Kujovic
la source

Réponses:

12

Oui, comme requis par POSIX , les commandes démarrées en arrière-plan &ont leur entrée standard redirigée depuis /dev/null.

Et en effet

{ cmd <&3 3<&- & } 3<&0

est le moyen le plus évident de contourner ce problème.

Cependant, la raison pour laquelle vous souhaitez exécuter une partie du pipeline en arrière-plan n'est pas claire.

Stéphane Chazelas
la source
la raison était d'obtenir le PID d'une commande spécifique à l'intérieur de la chaîne de tuyaux (cmd1 | {cmd2 &; pid2 = $ !;} | cmd3 ..., donc / dev / null == & 0 est standard pour les processus BG, savez-vous aussi pourquoi "0 <& 0" fonctionne dans bash ... et est-ce sûr?
Asain Kujovic
3
@OmerMerdan POSIX dit Dans tous les cas, la redirection explicite de l'entrée standard doit remplacer cette activité , ce qui contredit en quelque sorte ce qu'elle a dit ci-dessus, donc je crois que l' bashinterprète (et cela semble être une interprétation raisonnable) comme annulant la /dev/nullredirection. Maintenant, peu d'obus font la même chose. Ash et pdksh ne le font pas.
Stéphane Chazelas
Pourquoi est-ce la 3<&-pièce nécessaire et est-il sûr de l'utiliser (ne fermera-t-il pas le tuyau avant la lecture complète de l'ir)?
mvorisek
1
@Mvorisek, que fd 3 n'est utilisé que temporairement pour restaurer le stdin d'origine. Nous le fermons car il cmdn'en a pas besoin. Nous le fermons après l'avoir doublé sur fd 0 ( <&3abréviation de 0<&3).
Stéphane Chazelas
1
@Mvorisek, nohupredirige également stdin vers / dev / null, vous aurez besoin: { nohup sh -c 'cmd <&3 3<&-' & } 3<&0. Ou(trap '' HUP; cmd <&3 3<&- > nohup.out 2>&1 &) 3<&0
Stéphane Chazelas