![将标准输入发送到控制台并压缩文件](https://linux22.com/image/49393/%E5%B0%86%E6%A0%87%E5%87%86%E8%BE%93%E5%85%A5%E5%8F%91%E9%80%81%E5%88%B0%E6%8E%A7%E5%88%B6%E5%8F%B0%E5%B9%B6%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6.png)
我正在运行一个生成文本输出的专有程序。有点像记录器。
logger
我想在终端上查看此输出以观察服务器的呼吸,并将其发送到文本文件。所以通常我会这样做:
logger | tee /tmp/log.txt
但这些日志文件可能会变得足够大,足以淹没我的虚拟机磁盘空间。我不想将文本发送到未压缩的文本文件,而是希望立即对其进行压缩。所以我可能会这样做:
logger
在一个终端和
logger | gzip > /tmp/log.gz
在另一个终端。但这感觉不太好。
有没有一种方法可以通过一个命令来完成此任务,类似于使用tee
?这就是我想要的,这显然行不通,但也许你会明白:
logger | tee gzip > /tmp/log.txt
答案1
与ksh93
,zsh
或bash
:
logger | tee >(gzip > /tmp/log.txt.gz)
它使用了ksh
称为流程替代。>(gzip > /tmp/log.txt.gz)
是取代的与文件的路径(通常类似于/dev/fd/something
,但这也可能是临时的命名管道) 指的是管道的写入端。在该管道的另一(读取)端,外壳程序连接执行该命令的新进程(在后台运行)的标准输入gzip
。
所以,当tee
写入时文件,它实际上将数据馈送到gzip
.
在带有 的系统上/dev/fd/n
,您可以手动执行此操作(使用除 ksh93 之外的任何类似 Bourne 的 shell),例如:
{ logger | tee -a /dev/fd/3 | gzip > /tmp/log.txt.gz; } 3>&1
(尽管在这种情况下,/dev/fd/3
指的是我们在文件描述符 3 上使用的原始标准输入,而不是这里仅连接到 的标准输出3>&1
的管道)gzip
tee
和zsh
:
logger >&1 > >(gzip > /tmp/log.txt.gz)
那使用zsh
多操作系统该功能在内部zsh
实现了一种tee
将相同的输出重定向到多个文件(此处为原始 stdout ( >&1
) 和管道以gzip
再次使用进程替换。
logger
的标准输出实际上是管道的写入端。管道的另一端是一个 shell 进程,它读取它并像平常一样分发两个输出tee
。