gpt4 book ai didi

linux - 如何在执行 tar 时重定向 xz 的正常 stdout | xz?

转载 作者:太空宇宙 更新时间:2023-11-04 04:55:15 24 4
gpt4 key购买 nike

我需要使用像 xz 这样的压缩器来压缩巨大的 tar 文件。

我完全了解之前的问题,例如 Create a tar.xz in one commandUtilizing multi core for tar+gzip/bzip compression/decompression

从他们那里,我发现这个命令行大部分有效:

tar -cvf - paths_to_archive | xz -1 -T0 -v > OUTPUT_FILE.tar.xz

我使用管道解决方案,因为我绝对必须能够将选项传递给 xz。特别是,xz 非常占用 CPU 资源,因此我必须使用 -T0 来使用所有可用内核。这就是为什么我不使用其他可能性,例如 tar 的 --use-compress-program 或 -J 选项。

不幸的是,我真的想将 tar 和 xz 的所有日志输出(即非存档输出)捕获到日志文件中。在上面的示例中,注销始终由这些 -v 选项生成。

使用上面的命令行,该日志输出现在打印在我的终端上。

所以,问题是当你像上面那样使用管道连接 tar 和 xz 时,你不能用类似的东西结束命令行

>Log_File  2>&1

因为之前

> OUTPUT_FILE.tar.xz

有解决办法吗?

我尝试包装在这样的子外壳中

(tar -cvf - paths_to_archive | xz -1 -T0 -v > OUTPUT_FILE.tar.xz) >Log_File  2>&1

但这没有用。

最佳答案

tar 的正常 stdout 是 tarball,xz 的正常 stdout 是压缩文件。这些都不是您应该捕获的日志。 除输出文件本身之外的所有日志记录都专门写入两个进程的 stderr。

因此,您只需要重定向 stderr,并且不能重定向 stdout,除非您希望输出文件与日志记录混合在一起。

{ tar -cvf - paths_to_archive | xz -1 -T0 -v > OUTPUT_FILE.tar.xz; } 2>Log_File
<小时/>

顺便说一句 - 如果您好奇为什么 xz -v 在输出到 TTY 时会打印更多内容,答案是 in this line of message.c :只有当 isatty(STDERR_FILENO) 为 true 时,才会设置 progress_automatic 标志(告诉 xz 设置一个计时器来触发 SIGALRM ——它将其视为应该每秒打印一次状态的指示)。因此,在 stderr 被重定向到文件后,xz 根本不再打印此输出;问题不在于它没有正确重定向,而在于它不再存在

但是,如果您真的愿意的话,您可以每秒从您自己的代码发送 SIGALRMxz:

{
xz -1 -T0 -v > OUTPUT_FILE.tar.xz < <(tar -cvf - paths_to_archive) & xz_pid=$!
while sleep 1; do
kill -ALRM "$xz_pid" || break
done
wait "$xz_pid"
} 2>Log_File

(避免将 xz 执行所需时间四舍五入到最接近的秒的代码是可能的,但留给读者作为练习)。

关于linux - 如何在执行 tar 时重定向 xz 的正常 stdout | xz?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48452726/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com