据我所知,我可以使用tee命令将标准输出分为屏幕和其他文件:
command -option1 -option2 argument | tee file1 file2 file3
是否可以使用tee将输出重定向到命令而不是文件,以便从理论上讲我可以创建命令链?
据我所知,我可以使用tee命令将标准输出分为屏幕和其他文件:
command -option1 -option2 argument | tee file1 file2 file3
是否可以使用tee将输出重定向到命令而不是文件,以便从理论上讲我可以创建命令链?
Answers:
您可以在的命令行上使用命名管道(http://linux.die.net/man/1/mkfifo),tee
并在命名管道上读取命令。
mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2
当command
完成时,tee
将关闭命名管道,这将用信号在每个的EOF(读取的0字节)/tmp/dataN
,这通常终止cmdN
进程。真实的例子:
$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37
由于后台进程,外壳程序在程序输出之前返回了提示。所有三个实例均wc
正常终止。
如果我理解正确,你正在寻找的等价tee file1 file2 file3
,但不是写相同的数据三个文件file1
,file2
而且file3
,你要管相同的数据分成三个命令cmd1
,cmd2
和cmd3
,即
… | ??? cmd1 cmd2 cmd3
应该等于
… | cmd1 &
… | cmd2 &
… | cmd3 &
除了那只…
会执行一次。
有两种方法可以做到这一点。
Ksh93,bash和zsh支持进程替换。这是管道的概括,它允许命令的参数成为一个文件,该文件在写入时会将数据作为输入传递给命令(还有输入变体,当读取该变量时,它会获取命令输出的数据) 。那是,
echo hello | tee >(cmd1)
打印hello
到标准输出并且另外运行cmd1
以hello
作为输入。
因此,例如,如果您要复制的输入somecommand
并将其传递给cmd1
和cmd2
,则可以使用
somecommand | tee >(cmd1) | cmd2
如果您的外壳不支持进程替换,则可以改用命名管道。有关如何工作的信息,请参阅Arcege的答案。命名管道不如进程替换方便,因为您必须创建它们并删除它们,然后手动启动和同步过程。它们具有完全可移植的优点,而并非所有外壳程序都支持进程替换。它们也可以用在流程替代的场景之外。
在后台,在某些系统上,进程替换在内部使用命名管道。但是,在大多数系统上,它依赖于表示文件描述符的命名文件。
pee
从moreutils
。
我很惊讶没有人提到pee
moreutils(https://joeyh.name/code/moreutils)的命令。