dd 与 cat —— 如今 dd 仍然有意义吗?

dd 与 cat —— 如今 dd 仍然有意义吗?

我最近意识到我们可以使用尽可能cat多的dd实际上比dd

我知道这dd对于处理磁带很有用,其中块大小实际上关系到正确性,而不仅仅是性能。然而如今,有没有什么情况是dd可以做cat而不能做的呢? (在这里,我认为小于 20% 的性能差异是无关紧要的。)

具体的例子就更好了!

答案1

在外观上,dd是 IBM 操作系统中的一个工具,保留了其外在外观(其参数传递),它执行一些很少使用的功能(例如 EBCDIC 到 ASCII 的转换或字节顺序反转……现在不常见)。

曾经认为在同一磁盘上复制大数据块的速度dd更快(由于更有效地使用缓冲),但这不是真的,至少在今天的 Linux 系统上是这样。

我认为某些dd选项在处理磁带时很有用,其中读取实际上是按块执行的(磁带驱动程序不会像磁盘驱动程序那样隐藏存储介质上的块)。但我不知道具体情况。

dd任何其他 POSIX 工具无法(轻松)完成的一件事是取前 N 个字节一条流的。许多系统都可以使用 来完成此操作head -c 42,但是head -c虽然很常见,但在 POSIX 中并不存在(并且目前在 OpenBSD 等平台上不可用)。 (tail -c是 POSIX。)此外,即使head -c存在,它也可能从源中读取太多字节(因为它内部使用 stdio 缓冲),如果您正在从仅读取就会产生影响的特殊文件中读取,这就是一个问题,或者当其余数据应留给另一个进程读取时,从管道中读取。 (当前的 GNU coreutils 使用 读取精确计数head -c,但 FreeBSD 和 NetBSD 使用 stdio。)

更一般地说,dd为底层文件 API 提供一个接口,该接口在 Unix 工具中是唯一的:dd只能覆盖或截断一份文件在任何一点或者寻找在一个文件中。 (这是dd独特的能力,而且是一项重要的能力;奇怪的是,它dd最出名的是其他工具可以做的事情。)

  • 大多数 Unix 工具会覆盖其输出文件,即擦除其内容并从头开始。当您>在 shell 中使用重定向时也会发生这种情况。

  • 您可以通过>>shell 中的重定向或使用tee -a.

  • 如果您想通过删除所有数据来缩短文件在某一点之后,这是由底层内核和 C API 通过truncate函数,但不被任何 POSIX 命令行工具公开除了dd:

      dd if=/dev/null of=/file/to/truncate seek=1 bs=123456  # truncate file to 123456 bytes
    

    (但是,许多现代系统都提供了truncate实用程序。)

  • 如果您想覆盖文件中间的数据,同样可以在底层 API 中通过以下方式实现:开幕用于写入而不截断的文件(并调用lseek如有必要,移动到所需位置),但只能dd打开文件而不进行截断或追加,或者寻找从外壳(更复杂的例子)。

      # zero out the second kB block in the file (i.e. bytes 1024 to 2047)
      dd if=/dev/zero of=/path/to/file bs=1024 seek=1 count=1 conv=notrunc
    

所以…作为一个系统工具,dd几乎没什么用,甚至危险。作为一个文本(或二进制文件)处理工具,它是相当有价值的!

答案2

还没有人提到你可以使用 dd 来创建稀疏文件,但truncate也可用于相同目的。

dd if=/dev/zero of=sparse-file bs=1 count=1 seek=10GB

这几乎是即时的,并创建一个可以用作环回文件的任意大文件,例如:

loop=`losetup --show -f sparse-file`
mkfs.ext4 $loop
mkdir myloop
mount $loop myloop

好处是它最初只使用单个磁盘空间块,此后仅根据需要增长(10GB 文件的 ext4 格式在我的系统上消耗 291 MB)。用于du查看实际使用了多少磁盘空间——ls仅报告文件可能增长到的最大大小。

答案3

dd命令包含很多 cat 无法容纳的选项。也许在您的使用案例中, cat 是一个可行的替代品,但它不是 dd 替代品。

一个例子是用来dd复制某事物的一部分,但不是整个事物。也许您想根据设备上的已知位置从 iso 映像或硬盘驱动器的分区表中间删除一些位。您dd可以指定允许这些操作的开始、停止和数量选项。

这些选项dd使其对于细粒度数据操作不可或缺,而cat* 只能对整个文件对象、设备或流进行操作。

*正如 Gilles 在评论中指出的那样,可以cat与其他工具结合来隔离某些对象的某些部分,但cat仍然可以对整个对象进行操作。

答案4

dd对于备份硬盘驱动器或其他存储设备的引导扇区 ( dd if=/dev/sda of=boot_sector.bin bs=512 count=1) 以及稍后重写它 ( dd if=boot_sector.bin of=/dev/sda) 非常有用。它对于备份加密卷的标头同样有用。

cat也许可以扭曲这样做,但我不相信它的重写部分。很难cat只读/写一定数量的字节。

相关内容