linux tar -T - 无法即时运行

linux tar -T - 无法即时运行

我发现 Linux GNU Tar 存在一些问题。当我使用选项

-T -  (for file list from stdin) or
-T named_pipe_file    ,

这无法即时工作。例如,简单的交互式脚本:

while read x; do echo $x; done|\
tar cvf tar.tar -T -

仅当我按 ^D 标记输入 EOF 时,tar 才开始归档,当我使用命名管道时情况也一样:

mkfifo named_pipe
tar cvf tar.tar -T named_pipe
while read x; do echo $x; done >named_pipe

tar 似乎会进行一些缓冲。但是缓冲时间有多长?我必须将大量文件重新打包到 TAR,但磁盘空间却很少。然后我必须即时执行此操作。我使用 tar 选项 --remove-files 来实现这一点。但是如果没有 -T 选项的交互性,这是不可能的。在计划中,代码的“while”部分应该按顺序将文件解压到文件,并等待 TAR 进行删除,然后再处理下一个文件。感谢您的想法 :)

我的 tar 版本:tar (GNU tar) 1.26 (C) 2011 FSF

答案1

tar能够附加到已经存在的档案中,因此您可以执行以下操作:

touch tarfile.tar
command_that_produces_file_list | xargs tar rf tarfile.tar

不幸的是,这不适用于动态压缩。幸运的是,tar格式足够简单,我们可以做一些破解:

command_that_produces_file_list | {
  xargs -i sh -c 'tar c {} | head -c $(( (`stat --printf="%s" {}` + 511) / 512 * 512 + 512))';
  dd if=/dev/zero bs=512 count=2 2>/dev/null;
} | compression_utility

tar对于每个文件,输出由一个 512 字节的标头和随后的足以容纳文件数据的 512 字节块组成。然后,它附加至少 2 个 512 字节的零块。此代码的作用是捕获 tar 的输出并删除多余的零块,将来自多次调用的输出组合tar在一起,然后粘贴在终止的零块上。输出通过管道发送到压缩实用程序,该实用程序与tars 同时运行。

答案2

好消息。我收到错误报告的答复[电子邮件保护],引用:

发件人:Sergey Poznyakoff 日期:
2013 年 9 月 5 日星期四 08:40:40 +0300 主题:回复:[Bug-tar] gnu tar,来自 stdin 或命名管道的选项 -T 不是交互式的

你好,Grzegorz,

这已在 git HEAD 中修复(从提交 1fe0c83d 开始)。

问候,谢尔盖

然后我正在等待 Linux 发行版修复这个问题:)

答案3

阅读这个解释(第一个答案):管道命令按照什么顺序运行?

您看到的是 tar 在开始处理之前阻止输入列表的完成。可以说,与输入并行进行处理,逐个处理可能很有用,但我认为 GNU Tar 不支持这一点。

我只能猜测,等待整个列表是为了避免处理命令行参数的“内部程序”的复杂性 - 例如如何处理“--append 和 --remove-files”。我认为大多数人更喜欢批量删除所有文件归档已完成,并且不是像本例中希望的那样即时完成。

GNU 的人通常都非常友好,你可以问为什么这不是一个功能,如何使用其他工具来实现它,甚至请求这在将来成为 Tar 的一部分;

https://lists.gnu.org/mailman/listinfo/help-tar

相关内容