我想执行一个命令,让该命令的输出得到 gzip'd 的运行,并回显/发出该命令的输出。
即,类似:
echo "hey hey, we're the monkees" | gzip --stdout > my_log.gz
除了行执行时,我想在标准输出上看到这个:
hey hey, we're the monkees
另一种方式(假设 shell 像bash
or zsh
):
echo "hey hey, we're the monkees" | tee >(gzip --stdout > my_log.gz)
公认的奇怪>()
语法基本上执行以下操作:
/tmp/
)()
并将 FIFO 绑定到该子命令上的标准输入那么tee
,最终看到的是这样的:
tee /tmp/arjhaiX4
所有gzip
看到的是它的标准输入。
对于 Bash,请参阅man bash
详细信息。它在重定向部分。对于 Zsh,请参阅man zshexpn
“进程替换”标题下。
据我所知,Korn Shell、经典 Bourne Shell 的变体(包括 ash 和 dash)以及 C Shell 不支持这种语法。
echo "hey hey, we're the monkees" | tee /dev/tty | gzip --stdout > my_log.gz
正如评论中指出的那样,/dev/stdout
可能比/dev/tty
在某些情况下效果更好。
喝杯漂亮的T恤!
tee 命令将标准输入复制到标准输出以及作为参数给出的任何文件。当您不仅想通过管道发送一些数据,而且还想保存副本时,这很有用
当我度过一个缓慢的下午时,这里有一些精彩的说明性 ascii-art...
+-----+ +---+ +-----+
stdin -> |cmd 1| -> stdout -> |tee| -> stdout -> |cmd 2|
+-----+ +---+ +-----+
|
v
file
正如 grayfade 在另一个答案中所展示的那样,“文件”不必是常规文件,而可以是 FIFO,让您将 tee 的输出通过管道传输到第三个命令中。
+-----+ +---+ +-----+
stdin -> |cmd 1| -> stdout -> |tee| -> stdout -> |cmd 2|
+-----+ +---+ +-----+
|
v
FIFO
|
v
+-----+
|cmd 3|
+-----+
只是发布一种不涉及触摸磁盘的方式:
echo "hey hey, we're the monkees" | (exec 1>&3 && tee /proc/self/fd/3 | gzip --stdout > my_log.gz)