Linux 如何重定向xz';What’什么时候开始?

Linux 如何重定向xz';What’什么时候开始?,linux,bash,tar,xz,Linux,Bash,Tar,Xz,我需要使用像xz这样的压缩机来压缩巨大的焦油档案 我完全了解以前的问题,如 和 从中,我发现这个命令行主要起作用: tar -cvf - paths_to_archive | xz -1 -T0 -v > OUTPUT_FILE.tar.xz 我使用管道解决方案,因为我必须能够将选项传递给xz。特别是,xz非常占用CPU,因此我必须使用-T0来使用所有可用的内核。这就是为什么我没有使用其他的可能性,比如tar——使用compress程序,或者-J选项 不幸的是,我真的想将tar和xz的

我需要使用像xz这样的压缩机来压缩巨大的焦油档案

我完全了解以前的问题,如 和

从中,我发现这个命令行主要起作用:

tar -cvf - paths_to_archive | xz -1 -T0 -v > OUTPUT_FILE.tar.xz
我使用管道解决方案,因为我必须能够将选项传递给xz。特别是,xz非常占用CPU,因此我必须使用-T0来使用所有可用的内核。这就是为什么我没有使用其他的可能性,比如tar——使用compress程序,或者-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

但是这不起作用。

首先
-cvf-
可以被
cv
代替

但是
tar cvf-
的正常标准输出是tar文件,该文件通过管道传输到
xz
。不确定我是否完全理解,可能是:

tar cv paths | xz -1 -T0 > OUTPUT.tar.xz 2> LOG.stderr

不确定是否实现了
-T0
,您使用的是哪个版本的xz?(也许值得一看)在某些系统上安装了与sudo apt get install pv一起安装的
pv
程序比
xz-v
更能显示管道的进度。它将以百分比的形式告诉您进度,预计到达时间:

size=$(du -bc path1 path2 | tail -1 | awk '{print$1}')
tar c paths 2> LOG.stderr | pv -s$size | xz -1 -T0 > OUTPUT.tar.xz

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

因此,您只需要重定向stderr,并且不能重定向stdout,除非您希望将输出文件与日志混为一谈

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

顺便说一句——如果你想知道为什么
xz-v
输出到TTY时会打印更多的内容,答案是:
progress\u automatic
标志(告诉xz设置计时器触发
SIGALRM
,它将其视为状态应每秒打印的指示)仅在
为TTY时设置(STDERR_FILENO)
为真。因此,在STDERR被重定向到文件后,
xz
不再打印此输出;问题不是它没有正确重定向,而是它不再存在

但是,如果您确实愿意,您可以每秒从自己的代码向
SIGALRM
发送
xz

{
  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-1-T0-v>OUTPUT_FILE.tar.xz

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

您是否尝试删除
-v
选项?根据文档,它启用了详细模式。另外还有
-q
用于抑制警告、通知和错误。有关详细信息,请参阅
其他选项部分:tee(1)是您的朋友,请参阅。另请参阅,请详细介绍“那不起作用”的错误描述?请给出一个例子,结果是什么,你期望得到什么。什么是“正常输出”你在说什么?正常的、通常的、预期的和预期的
xz
标准输出是压缩文件本身。在标准输出上没有任何其他内容可以捕获为人类可读的日志。@Igor:我知道-v启用额外输出,而-q将抑制该输出。我希望tar和xz都使用-v选项,因为我确实需要归档的所有“元数据”的日志记录,例如归档的所有文件的列表。是的。值得注意的是,他们没有给出任何关于如何确定归档失败的详细说明。(如果他们真正的语法有点不同,将
2>&1
放在
>输出文件.log.xz
之后,那么他们会将日志混合到.xz文件中,从而破坏它)@that otherguy,…坦白地说,如果他们被
xz
根据stderr是否是tty更改其日志而抛出,我一点也不惊讶——但如果这是真正的问题,他们应该编辑问题,使其明确无误。@Charles:我现在看到了你的答案,很抱歉我昨天错过了它。我认为这是正确的,非常感谢有几点需要补充。@Charles首先是最后的分号(;)在你的花括号内是非常重要的。我第一次尝试你的语法时忽略了这一点,但它以一个奇怪的错误失败了。我相信你知道这一点,我只是向阅读本文的其他人提及这一点。@Charles Second,你强调的tar和xz总是记录到stderr需要澄清。是的,如果你让他们写他们的archiv输出到stdout,然后他们将日志切换到stderr。这对我来说非常有意义——他们必须这样做,否则他们会将日志数据与存档数据混合!然而,我被愚弄了,因为我通常让tar将其存档数据写入文件。在这种情况下,tar将普通日志写入stdout而不是stderr。证明:
tar-cvf output\u file.tar路径\u to\rchive 1>stdout.log 2>stderr.log
将日志(例如从-v标志)写入
stdout.log
,而
stderr.log
保留为空。
{ tar -cvf - paths_to_archive | xz -1 -T0 -v > OUTPUT_FILE.tar.xz; } 2>Log_File
{
  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