我想要执行一个命令,让该命令的输出被动态压缩为gzip格式,并同时打印/保存该命令的输出。
例如:
echo "hey hey, we're the monkees" | gzip --stdout > my_log.gz
除了执行这一行代码之外,我希望在标准输出中看到这个:
hey hey, we're the monkees
另一种方法(假设使用像bash
或zsh
这样的shell):
echo "hey hey, we're the monkees" | tee >(gzip --stdout > my_log.gz)
这个有点奇怪的 >()
语法基本上是做以下几件事情:
/tmp/
中)()
中执行命令,并将该 FIFO 绑定到该子命令的 stdin 上然后,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
更有效。
来一杯美味的tee吧!
tee命令将标准输入复制到标准输出,并复制到提供给它的任何文件中。当你不仅想要将数据传送到管道中,还想要保存一份副本时,这非常有用。
由于我今天下午比较闲,就画了一些精美的ASCII艺术...
+-----+ +---+ +-----+
stdin -> |cmd 1| -> stdout -> |tee| -> stdout -> |cmd 2|
+-----+ +---+ +-----+
|
v
file
正如@greyfade在另一个回答中所示,'file'不必是普通文件,而可以是FIFO,让您将Tee的输出导入到第三个命令中。
+-----+ +---+ +-----+
stdin -> |cmd 1| -> stdout -> |tee| -> stdout -> |cmd 2|
+-----+ +---+ +-----+
|
v
FIFO
|
v
+-----+
|cmd 3|
+-----+
cmd 3
写作>(cmd 3)
。 - SamB这里提供一种不需要操作磁盘的方法:
echo "hey hey, we're the monkees" | (exec 1>&3 && tee /proc/self/fd/3 | gzip --stdout > my_log.gz)
mkfifo
并在不同的控制台中运行所有这些命令。 - greyfade>(trap''INT; gzip --stdout > my_log.gz)
忽略SIGINT似乎可以保存它。 - jozxyqk