Une ligne avec 2 fichiers tmp (pas ce que vous voulez) serait:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
Avec bash , vous pouvez essayer:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
La 2ème version vous rappellera plus clairement quelle entrée était laquelle, en affichant
-- /dev/stdin
vs ++ /dev/fd/63
ou quelque chose, au lieu de deux fds numérotés.
Pas même un tube nommé n'apparaîtra dans le système de fichiers, du moins sur les systèmes d'exploitation où bash peut implémenter la substitution de processus en utilisant des noms de fichiers comme /dev/fd/63
pour obtenir un nom de fichier que la commande peut ouvrir et lire pour réellement lire à partir d'un descripteur de fichier déjà ouvert que bash défini avant d'exécuter la commande. (c'est-à-dire que bash utilise pipe(2)
avant fork, puis dup2
pour rediriger de la sortie de quux
vers un descripteur de fichier d'entrée pour diff
, sur fd 63.)
Sur un système sans "magique" /dev/fd
ou /proc/self/fd
, bash pourrait utiliser des tubes nommés pour implémenter la substitution de processus, mais il les gérerait au moins lui-même, contrairement aux fichiers temporaires, et vos données ne seraient pas écrites sur le système de fichiers.
Vous pouvez vérifier comment bash implémente la substitution de processus avec echo <(true)
pour imprimer le nom de fichier au lieu de le lire. Il imprime /dev/fd/63
sur un système Linux typique. Ou pour plus de détails sur exactement les appels système que bash utilise, cette commande sur un système Linux tracera les appels système de fichiers et de descripteurs de fichiers.
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Sans bash, vous pourriez créer un tube nommé . Utilisez -
pour dire diff
de lire une entrée de STDIN, et utilisez le tube nommé comme l'autre:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
Notez que vous ne pouvez diriger qu'une seule sortie vers plusieurs entrées avec la commande tee:
ls *.txt | tee /dev/tty txtlist.txt
La commande ci-dessus affiche la sortie de ls * .txt vers le terminal et la renvoie dans le fichier texte txtlist.txt.
Mais avec la substitution de processus, vous pouvez utiliser tee
pour alimenter les mêmes données dans plusieurs pipelines:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
mkfifo a; cmd >a& cmd2|diff a -; rm a