当输出文件为/ dev / null时,为什么tar似乎会跳过文件内容?


21

我有一个包含超过400 GiB数据的目录。我想检查所有的文件都没有错误被读取,所以一个简单的方法,我认为是tar/dev/null。但是相反,我看到以下行为:

$ time tar cf /dev/null .

real    0m4.387s
user    0m3.462s
sys     0m0.185s
$ time tar cf - . > /dev/null

real    0m3.130s
user    0m3.091s
sys     0m0.035s
$ time tar cf - . | cat > /dev/null
^C

real    10m32.985s
user    0m1.942s
sys     0m33.764s

在运行了很长时间之后,上面的第三个命令被Ctrl+ 强制停止C。此外,当前两个命令正在工作时,包含该存储设备的活动指示器.几乎始终处于空闲状态。使用第三个命令,指示灯会持续亮起,这意味着非常忙碌。

如此看来,当tar能够发现其输出文件为时/dev/null,即当/dev/null直接打开以具有tar写入的文件句柄时,文件主体就会被跳过。(添加v选项tar的确会打印tar红色目录中的所有文件。)

所以我想知道,为什么会这样呢?是某种优化吗?如果是,那么为什么还要tar针对这种特殊情况进行如此可疑的优化呢?

我在Linux 4.14.105 amd64上使用带有glibc 2.27的GNU tar 1.26。


7
作为实用的替代方法,考虑类似的东西find . -type f -exec shasum -a256 -b '{}' +。它不仅实际读取并校验所有数据,而且还存储了输出,以后可以重新运行以检查文件内容是否未更改。
Ilmari Karonen

要衡量事情,您也可以使用pvtar -cf - | pv >/dev/null。那回避了问题,并为您提供了进度信息(各种pv选项)
xenoid

您遇到了一个著名的GNU tar错过功能。使用gtar -cf /dev/zero ...得到你喜欢的东西。
schily

Answers:


25

有据可查的优化

在将存档创建到时/dev/null,GNU tar会尝试最小化输入和输出操作。与GNU tar一起使用时,Amanda备份系统具有使用此功能的初始大小调整过程。


4
啊,这在我安装的手册页中没有描述。应该应该尝试一下info tar...
Ruslan

9
他们应该真正使手册页和信息页保持同步,这实际上是一个错误,并非如此
Xen2050

9
@Ruslan对于大多数GNU实用程序,手册页仅包含一个简短的摘要,基本上只有在您记住它具有执行某项操作的选项但不记得该选项的名称时才足够好。完整的文档格式不能很好地转换为手册页,并且可以info在浏览器中以HTML或HTML的形式获得。
吉尔斯(Gilles)“所以

18
这是一个公认的问题
欧文

8

这可能在多种程序中发生,例如,我只是在使用时就有过这种行为cp file /dev/null。几秒钟后返回了该命令,而不是估计我的磁盘读取速度。

据我所知,它是在Solaris或AIX上运行的,但是该原理适用于所有类型的unix-y系统。

在旧时代,当一个程序中复制文件到某个地方,它会之间交替read是从磁盘获取一些数据(或任何文件描述符指)内存调用(有保证一切都在那里当read收益)和write电话(这会占用一部分内存并将内容发送到目标位置)。

但是,至少有两种更新的方法可以实现相同的目的:

  • Linux具有系统调用copy_file_range(根本不能移植到其他unix)和sendfile(某种程度可移植;最初旨在将文件发送到网络,但现在可以使用任何目的地)。它们旨在优化传输;如果程序使用其中之一,则很容易想到内核会识别目标为目标/dev/null并将系统调用转换为无操作

  • 程序可以使用mmap而不是获取文件内容read,这基本上是指“当我尝试访问该内存块时确保数据在那里”,而不是“当系统调用返回时确保数据在那里”。因此,程序可以mmap使用源文件,然后调用write那部分映射的内存。但是,由于写入/dev/null不需要访问写入的数据,因此永远不会触发“确保其存在”条件,从而也不会读取文件。

不知道gnu tar是否在检测到正在写入时使用这两种机制中的任何一种,以及这两种机制中的哪一种/dev/null,但是它们是为什么任何程序(用于检查读取速度)都应| cat > /dev/null代替> /dev/null- 运行的原因,以及为什么| cat > /dev/null要使用在所有其他情况下都应避免


我认为GNU tar信息页中的含义(请参阅其他答案)是它具有一种特殊的模式,该模式大概只是统计文件而无需打开它们。实际上,我只是检查tar cf /dev/null foo*了几个文件,是的,只是newfstatat(..., AT_SYMLINK_NOFOLLOW)系统调用,甚至没有一次open()可以更新时间的文件。但是+1用来描述可能发生这种情况的机制,而无需专门检测它。
Peter Cordes

mmap解释应该显示为“访问读取的数据”而不是“访问已写入的数据”吗?
韦恩·康拉德

另请参见splice(2)Linux。实际上,将其替换cat > /dev/nullpv -q > /dev/nullsplice()在Linux 上使用)可能会减少开销。或dd bs=65536 skip=9999999999 2> /dev/nullwc -c > /dev/nulltail -c1 > /dev/null...
斯特凡·Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.