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 si:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
La 2ème version sera plus clairement vous rappeler quelle entrée était qui, en montrant
-- /dev/stdin
par rapport à ++ /dev/fd/63
ou quelque chose, au lieu de deux fds numérotés.
Pas même un tube nommé apparaît dans le système de fichiers, au moins sur les systèmes d'exploitation où bash peut mettre en œuvre la substitution de processus en utilisant des noms comme /dev/fd/63
pour obtenir un nom de fichier que la commande peut ouvrir et lire à lire en fait à partir d'un descripteur de fichier déjà ouvert que bash a mis en place avant l'exécution de la commande. (C.-à-bash utilise pipe(2)
avant la fourche, puis dup2
pour rediriger de la sortie de quux
à 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 peut utiliser Des canaux nommés pour implémenter la substitution de processus, mais au moins les gérer eux-mêmes, contrairement aux fichiers temporaires, et vos données ne seraient pas écrites dans 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 d'en lire. Il imprime /dev/fd/63
sur un système Linux typique. Ou pour plus de détails sur exactement ce que le système appelle bash utilise, cette commande sur un système Linux le fichier de trace et système descripteur de fichier appelle
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Sans bash, vous pouvez faire une pipe nommé.Utilisez -
pour dire diff
lire une entrée de STDIN et utiliser le canal 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 une sortie à entrées multiples avec la commande tee :
ls *.txt | tee /dev/tty txtlist.txt
les affichages de commande ci-dessus la sortie de ls * txt à la borne et les sorties dans le fichier texte txtlist.txt.
Mais avec la substitution de processus, vous pouvez utiliser tee
pour nourrir les mêmes données dans plusieurs pipelines:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
même sans bash, vous pouvez utiliser 'mkfifo a du fifo temporaire; cmd> a & cmd2 | diff a -; rm a' – unhammer
Vous pouvez utiliser un tube standard pour l'un des arguments: 'pipeline1 | diff -u - <(pipeline2) '. Ensuite, la sortie vous rappellera plus clairement quelle entrée était, en montrant '-/dev/stdin' vs'/dev/fd/67' ou quelque chose, au lieu de deux fds numérotés. –
La substitution de processus ('foo <(pipe)') ne modifie pas le système de fichiers. ** Le tuyau est * anonyme *; il n'a pas de nom dans le système de fichiers **. Le shell utilise l'appel système 'pipe' pour le créer, pas' mkfifo'. Utilisez 'strace -f -file, desc, clone, execve bash -c '/ bin/true | diff -u - <(/ bin/true) ''pour suivre les appels système de fichier et de descripteur de fichier si vous voulez voir par vous-même.Sous Linux, '/ dev/fd/63' fait partie du système de fichiers virtuel'/proc'; il a automatiquement des entrées pour chaque descripteur de fichier, et ce n'est pas une copie du contenu. Vous ne pouvez donc pas appeler cela un "fichier temporaire" à moins que "foo 3