En expérimentant la redirection de sortie et la substitution de processus, je suis tombé sur la commande suivante et sa sortie résultante:
me @ elem: ~ $ echo foo>> (chat); barre d'écho bar moi @ elem: ~ $ foo
(Oui, cette nouvelle ligne vide à la fin est intentionnelle.)
Alors bash echo's bar, imprime mon invite habituelle, echo's foo, echo's a newline, et laisse mon curseur là. Si j'appuie de nouveau sur Entrée, il affichera mon invite sur une nouvelle ligne et laissera le curseur le suivre (comme prévu lorsque quelqu'un frappe Entrée sur une ligne de commande vide).
Je m'attendais à ce qu'il écrive foo dans un descripteur de fichier, cat le lit et foo echo, la deuxième barre d'écho echo, puis reviens à l'invite de commande. Mais ce n'est clairement pas le cas.
Quelqu'un pourrait-il expliquer ce qui se passe?
bash
shell
process-substitution
concurrency
Stanley Yu
la source
la source
Réponses:
Vous pouvez voir
foo
s'afficher avantbar
, aprèsbar
ou même après l'invite, selon le moment. Ajoutez un peu de retard pour obtenir un timing cohérent:bar
apparaît immédiatement, puisfoo
après une seconde, puis l'invite suivante après une autre seconde.Ce qui se passe, c'est que bash exécute les substitutions de processus en arrière-plan.
sleep 1; cat
et configure un canal vers celui-ci.echo foo
. Comme cela ne remplit pas le tampon du tube, laecho
commande se termine sans blocage.echo bar
.sleep 2
.sleep 1
.sleep 1
retourne dans le sous-processus. Le sous-processus s'exécutecat
.cat
copie son entrée dans sa sortie (qui s'affiche à l'écran) et revient.sleep 2
revient. Le processus shell principal termine son exécution et vous obtenez la prochaine invite.la source
Vous n'avez pas besoin de substitution de processus pour obtenir cet effet. Essaye ça:
Vous obtiendrez à peu près le même résultat (sans le
bar
; je laisserai cela comme un exercice) et pour la même raison. Dans les deux cas,cat
démarre comme tâche d'arrière-plan. Dans ma ligne ici, c'est explicite. Dans le cas de la substitution de processus, c'est aussi explicite - c'est un processus distinct attaché à un descripteur de fichier de nom - mais ce n'est peut-être pas aussi évident.Le processus enfant ne se termine pas nécessairement avant d'
bash
imprimer l'invite suivante. Et comme sa sortie est mise en mémoire tampon, elle ne produit rien tant qu'elle n'est pas terminée. À ce stade, bash vient d'imprimer$
sur stderr, et maintenant le processus d'arrière-plan se termine après l'impressionfoo
et une nouvelle ligne.la source