我需要找到比 x 天新的文件,然后将其转换为 gzip,但我想使用 pigz 来完成。
现在我正在以缓慢的方式进行;这有效:
find /path/to/src -type f -mtime -90 | xargs tar -zcf archive.tar.gz
但是pigz
速度非常快,所以我想用 pigz 来运行这个 gzip。我试过这个,但它不工作:
find /path/to/src -type f -mtime -90 | xargs tar -zcf | pigz > archive.tar.gz
它返回一个错误,因为我只是猜到了要做什么(并尝试了几种方法):
tar (child): /path/to/src: Cannot open: Is a directory
tar (child): Error is not recoverable: exiting now
如何采取第一条有效的线路并将其输送到pigz?
假设 GNU 或 libarchive 的
tar
:(
--no-recursion
这里不是绝对必要的,因为报告的文件find
不是目录类型)。不要使用(无论如何,如果你使用and 's
xargs
只能在find
' 输出上使用),因为它最终可能会运行多个,所以你最终会得到只包含最后一批的存档。-0
find
-print0
tar
在这里,我们
tar
通过管道直接将文件列表传递给,-T -
因此可以通过这种方式传递的文件数量没有限制。这也意味着tar
可以在找到文件后立即开始存档。star
(@schily的 (RIP)tar
)还具有内置find
功能:不过,您也可以使用以下语法采用与上述其他两种方法相同的方法:
tar
是一个非常不便携的命令。甚至 tar 格式也是不可移植的。X/Open / SUSv2 曾经指定一个tar
命令(和cpio
),但他们最终放弃了它,因为无法协调tar
来自不同供应商的 s,而是 POSIX / SUS 想出了pax
作为两者的替代品。pax
从标准输入获取文件列表,但不幸的是,换行符分隔而不是 NUL 分隔,这意味着它不能归档任意文件名,尽管某些pax
实现支持-0
扩展名(虽然可以替换为find
's-print0
也不是 POSIX-exec printf '%s\0' {} +
)。所以,有了这些:(请注意,每个 POSIX 的默认输出格式是未定义的,这是 . 的另一个弱点
pax
。它最大的弱点是它的采用率非常低)。在任何支持进程替换的 shell (例如 bash、ksh、zsh)上使用 GNU tar:
这用于进行压缩,并通过or选项和进程替换
pigz
将(NUL 分隔的)文件列表从 的输出中包含在存档中。find ... -print0
-T
--files-from=FILE
或者,如果您使用的是仅具有 POSIX 功能的极简 shell(例如 ash 或 dash,或者 bash 运行为
/bin/sh
或使用--posix
或set -o posix
使用POSIXLY_CORRECT
环境变量集),您可以将 NUL 分隔的文件名列表通过管道传输到 GNU tar。以下选项告诉 tar 从标准-
输入-T
读取文件列表。其中任何一个都适用于任何有效的文件名,即使是那些包含空格、换行符和 shell 元字符的文件名。它还避免了@Kusalananda 在他的评论中提到的文件名过多的问题。
顺便说一句,您可能想使用pixz而不是
pigz
. 它进行xz压缩(通常比 gzip 压缩得更好,但速度较慢),如果 pixz 检测到类似 tar 的输入,它会添加一个索引来加速特定文件的提取。顺便说一句,两者pixz
都xz-utils
为最常见的 Linux 发行版打包,所以应该很容易安装。