单行包含2个tmp文件(不是您想要的文件)将是:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
使用bash,您可以尝试:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
第二版将通过显示
-- /dev/stdin
vs. ++ /dev/fd/63
或其他内容,而不是两个编号的fds,来更清楚地提醒您输入的是哪个。
甚至命名管道都不会出现在文件系统中,至少在bash可以通过使用文件名来实现进程替换的OS上,例如/dev/fd/63
获得命令可以打开和读取的文件名,以从bash设置的已经打开的文件描述符中实际读取文件。在执行命令之前。(即bash pipe(2)
在fork之前使用,然后在fd 63上dup2
从输出重定向quux
到的输入文件描述符diff
。)
在没有“ magical” /dev/fd
或的系统上/proc/self/fd
,bash可以使用命名管道来实现进程替换,但与临时文件不同,它至少可以管理它们本身,并且您的数据不会被写入文件系统。
您可以检查bash如何实现进程替换echo <(true)
以打印文件名而不是读取文件名。它/dev/fd/63
在典型的Linux系统上打印。或者要获得有关bash确切使用的系统调用的更多详细信息,在Linux系统上的此命令将跟踪文件和文件描述符系统调用
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
没有bash,您可以创建一个命名管道。使用-
告诉diff
从标准输入读一个输入,并使用命名管道作为其他:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
请注意,只能使用tee命令将一个输出传送到多个输入:
ls *.txt | tee /dev/tty txtlist.txt
上面的命令将ls * .txt的输出显示到终端,并将其输出到文本文件txtlist.txt。
但是,通过流程替换,您可以tee
用来将相同的数据馈送到多个管道中:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
mkfifo a; cmd >a& cmd2|diff a -; rm a