附加到压缩日志

附加到压缩日志

有几个 z 实用程序(zlesszcat),它们能够以透明的方式读取压缩文件的内容。

是否可以附加到压缩日志文件(任意格式,不一定是 gzip)?

我想要类似以下的东西(ztee具有感兴趣的功能的虚构实用程序):

echo "[ $( date ) ] message" | ztee -a file.log.gz

答案1

是的,但是没用。


gzip一些压缩文件格式(包括、bzip2和使用的格式xz原生支持串联。(它可能使用低级 API 时需要明确选择加入,但命令行解压器默认接受它。)

echo "test 1" | gzip >> log.txt.gz
echo "test 2" | gzip >> log.txt.gz
echo "test 3" | tee >(gzip >> log.txt.gz)
echo "test 4" | (tee /dev/fd/3 | gzip >> log.txt.gz) 3>&1
zcat log.txt.gz

(请注意,egzcat实际上只是一个 shellscript 包装器gunzip...)

然而,这意味着每条日志消息都是单独压缩的,而不考虑所有先前的内容。因此,如果你尝试链接许多短日志消息,你的压缩率将非常低,非常很差。(在我以这种方式压缩随机日志文件的测试中,生成的文件实际上成长到其原始大小的 120%,因为所有重复的“标题”开销。)

$ dmesg > test.log
$ cat test.log | gzip > test-single.log.gz
$ cat test.log | while read -r line; do
                     echo "$line" | gzip
                 done > test-concat.log.gz
$ du -h test*
500K     test-concat.log.gz
416K     test.log
64K      test-single.log.gz

据我所知,没有工具支持加载现有压缩文件的标头并使用它来压缩新数据。要实现这一点,您需要运行一个持久gzip进程并定期通过 stdin 向其提供日志。例如:

#!/bin/bash

# open a subprocess (the bash equivalent of 'popen')
coproc LOG { gzip >> log.txt.gz; }

echo "doing stuff" >&${LOG[1]}
echo "doing more stuff" >&${LOG[1]}
echo "still doing stuff" >&${LOG[1]}

# close its stdin to finish compression
exec {LOG[1]}>&-

在“标准” shell 中,你可以使用命名管道实现相同的功能,或者更简单地重定向整个剧本gzip。 (只需将同一条消息打印一次到 stdout,一次到 stderr,您就得到了tee。)


有关压缩流连接的更多信息:

相关内容