将标准输入发送到控制台并压缩文件

将标准输入发送到控制台并压缩文件

我正在运行一个生成文本输出的专有程序。有点像记录器。

logger

我想在终端上查看此输出以观察服务器的呼吸,并将其发送到文本文件。所以通常我会这样做:

logger | tee /tmp/log.txt

但这些日志文件可能会变得足够大,足以淹没我的虚拟机磁盘空间。我不想将文本发送到未压缩的文本文件,而是希望立即对其进行压缩。所以我可能会这样做:

logger

在一个终端和

logger | gzip > /tmp/log.gz

在另一个终端。但这感觉不太好。

有没有一种方法可以通过一个命令来完成此任务,类似于使用tee?这就是我想要的,这显然行不通,但也许你会明白:

logger | tee gzip > /tmp/log.txt

答案1

ksh93,zshbash:

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的管道)gziptee

zsh

logger >&1 > >(gzip > /tmp/log.txt.gz)

那使用zsh 多操作系统该功能在内部zsh实现了一种tee将相同的输出重定向到多个文件(此处为原始 stdout ( >&1) 和管道以gzip再次使用进程替换。

logger的标准输出实际上是管道的写入端。管道的另一端是一个 shell 进程,它读取它并像平常一样分发两个输出tee

相关内容