Tar 提取 tar 文件流

Tar 提取 tar 文件流

我有一个二进制文件(我们称之为displayFiles),它将同时获取多个 tar 文件并将 tar 文件打印到 stdout。然后我将 stdout 传输到tar

当二进制文件仅下载单个 tar 时,此方法可行。如果我一次获取多个 tar 并将它们通过管道传输到,tar此方法可行吗?displayFiles程序不会在一个文件和下一个文件之间暂停。

例如:

./displayFiles | { tar -xvf -; }

答案1

tar 档案的结尾由两个连续的零填充的 512 字节记录标记。从 stdin 读取时,tar应在读取两个零填充的记录后停止,以便下一个工具可以读取后面的数据(如果有)。

如果后面的数据是另一个 tar 存档,而下一个工具也是另一个,tar那么该工具将起作用。要提取 N 个串联存档,您需要调用tarN 次。除非……

GNUtar支持--ignore-zeros,因此单个用户tar可提取部分串联档案。但不是全部。

通常情况下,当 tar 遇到文件条目之间的零块(通常表示档案的结尾)时,它会停止读取。--ignore-zeros-i)允许 tar 完全读取在结尾之前包含零块的档案(即,损坏的档案或通过将多个档案连接在一起而创建的档案)。

--ignore-zeros( )选项-i默认关闭,因为许多版本的 tar 会在存档结束条目后写入垃圾,因为媒体的这一部分永远不应该被读取。[…]

来源

首先要尝试的是tarGNU ( --ignore-zeros) :-i

./displayFiles | tar -xivf -

如果您不能使用 GNUtar或任何支持类似 的实现--ignore-zeros,则需要调用tarN 次。如果事先不知道 N,则tar循环运行直至失败:

./displayFiles | while tar -xvf -; do :; done

在最好的情况下,期望This does not look like a tar archive在关闭其标准输出tar后尝试读取。displayFiles

请注意,在两个连续的零填充 512 字节记录之后带有额外数据(或垃圾)的 tar 存档仍然有效(即tar可以正常提取)。如果此类存档进入我们的循环,则下一个tar将读取额外数据。除了一个或几个极端情况外,额外数据将使工具失败,这将提前结束循环。但即使我们继续循环,除了一个或几个极端情况外,额外数据也会“使流不同步”,并且每个后续文件都将开始tar读取流,而不是从某个连接的存档开始的地方读取。因此,提前失败并不坏。

希望来自的 tar 档案displayFiles不包含额外数据。如果包含,则没有简单可靠的方法可以在串联档案流中找到单个档案。无论您使用--ignore-zeros还是循环,问题都存在。

如果您使用循环,无论如何,其中的一些操作tar都会失败,而且通常您不知道是否已处理所有数据。因此,请考虑添加一些命令来告诉您流是否已耗尽。示例:

./displayFiles | (while tar -xvf -; do :; done; exit "$(head -c 1 | wc -c)")

head -c 1不可移植。可移植替代品dd bs=1 count=1 2>/dev/null。)

退出状态0表示所有数据已被tar进程使用。它仅表示没有其他含义(特别是它不表示没有有意义的错误)。

答案2

tar -f FILE/tar --file=FILE仅接受一个文件,因此您要么使用单独的命令将cat所有文件连接在一起,要么使用循环或tar对每个文件运行一个命令。while readxargs

相关内容