Ce script:
#!/bin/bash tmppipe=/tmp/temppipe mkfifo $tmppipe echo "test" > $tmppipe cat $tmppipe exit
Ne se termine pas. Je suppose que la command de chat attend un EOF de la pipe; comment j'envoie un?
Non c'est
echo test > "$tmppipe" # BTW, you've got the quotes in the wrong places
qui se bloque. Plus précisément, c'est la shell qui ouvre le tuyau pour écrire avant de lancer l' echo
.
pipe
sont des mécanismes de communication inter-process, ils doivent être utilisés entre les process s'exécutant en même time . Ici, l' open(WR_ONLY)
( >
) bloquera jusqu'à ce qu'un autre process open
en mode lecture.
echo test > "$tmppipe" & cat < "$tmppipe"
va fonctionner parce que l' echo
et le cat
courent simultanément.
Sous Linux, vous pouvez vous en sortir avec:
exec 3<> "$tmppipe" echo test >&3 cat < "$tmppipe" exec 3<&-
Cela fonctionne parce que read + write open
s ( <>
) sur les pipes ne bloque pas sur Linux, et parce que le test\n
output par echo
est assez petit pour tenir dans le pipe, vous pouvez donc écrire et lire séquentiellement.
Cela ne fonctionnerait pas pour un rendement plus important comme:
exec 3<> "$tmppipe" seq 100000 >&3 cat < "$tmppipe" exec 3<&-
Parce que seq
remplirait le pipe (64kiB dans les versions actuelles de Linux) et bloquerait jusqu'à ce qu'un autre process lise datatables de ce pipe, ce qui n'arrivera jamais car cat
ne fonctionnera pas tant que seq
n'aura pas fini.
Notez que:
echo test 1<> "$tmppipe" cat < "$tmppipe"
ne fonctionnerait pas non plus parce que la command line echo
ouvrirait le tuyau, écrirait le test puis fermerait le tuyau (le système le détruirait alors qu'il n'y a plus de descripteur de file ouvert). La prochaine command line du cat
essaierait donc d'instancier un nouveau pipe (et de bloquer jusqu'à ce que quelque chose ouvre le file fifo pour l'écriture).
Il s'avère que la réponse est évidente – le tuyau est bloqué par echo
, et n'atteint jamais le chat!
Les tuyaux ne stockent pas de données. Lorsqu'un process tente d'écrire dans un tube, l'écriture ne peut pas être terminée tant que l'autre extrémité du tube n'est pas connectée.
Une façon de résoudre cet exemple particulier est d'utiliser
echo "test" > $tmppipe &
pour que le process d'écriture s'exécute en arrière-plan. De cette façon, il se trouve là des attentes, pendant que le script continue, jusqu'à ce qu'il atteigne le cat
et peut terminer.