dd 和 cat 在写入图像文件方面有什么区别?

dd 和 cat 在写入图像文件方面有什么区别?

将图像文件写入磁盘或 USB 驱动器时,指令通常使用dd,如下所示:

dd if=myimage.img of=/dev/sdb

这与以下说法有何不同:

cat myimage.img > /dev/sdb

我意识到dd有更多选项,例如count=...,但如果练习的目的是将整个文件写入设备,那么使用有什么好处dd

答案1

这个问题就像“我有一个可以绘制矩形的工具,另一个可以绘制菱形;哪一个是绘制正方形的正确工具?”

任何正方形都是矩形的特例,也是菱形的特例,因此可以使用这两种工具中的任一种。

dd和 也一样cat。前者可以进行转换、跳过和查找、调整缓冲区大小;但在简单情况下,它只读取一个文件(或块设备)并将原始数据写入另一个文件。后者可以将多个文件连接到一个流中,并进行一些可选的文本修改,但在简单情况下,只有一个输入文件,其内容(在 shell 支持下)流式传输到输出文件或设备。

这两种工具都很有用,不能为了另一个而放弃任何一个。它们的作用范围恰好在你问到的这个简单案例上重叠。


话虽如此,我认为至少有两个问题可以使dd 更好的选择成为合理的。

1. 阻止设备权限

要写入文件或设备,cat需要重定向其输出。您的 shell 会执行重定向,即打开目标文件。重定向到时,/dev/sdb您可能会遇到“权限被拒绝”的情况,除非您以以下身份登录. 运行 shell是有风险的,应该避免。

你可以尝试

sudo cat myimage.img > /dev/sdb

并失败,因为sudo不会影响 shell 完成的输出重定向。

另一方面这完全没有问题:

sudo dd if=myimage.img of=/dev/sdb

顺便提一下:如果您发现必须将输出重定向到具有受限访问权限的文件,那么您可以使用这个技巧:

some_command | sudo tee restricted_file > /dev/null

这引出了另一种完成这项工作的方法。该命令tee将其输入传递给多个文件和标准输出。在简单情况下,只有一个文件,标准输出将被丢弃:

sudo tee /dev/sdb < myimage.img > /dev/null

在这种情况下,输入重定向也不会受到影响sudo

2. 超越简单案例

想象一下一位制作厨房桌子的木匠。大多数桌子的桌面都是矩形的;菱形的桌子很少见。有一张桌面是方形的桌子需要制作。方形是菱形,也是矩形。木匠会使用适用于罕见的菱形桌子的方法吗?还是适用于常见的矩形桌子?这两种方法都应该适用于方形桌子,尽管他每个工作日都制作矩形,所以改变方法毫无意义。

回到catdd。在我看来(和我的实践),几乎不需要连接多个图像以将它们全部写入块设备。这肯定是的工作cat。该工具可以做更多的事情,但你不想要它:选项以文本文件为目标,因此当与图像文件一起使用时,它们可以使您的二进制数据无效。

dd现在,当我从设备读取或写入时,提供的选项通常对我有用:

  • conv=noerror– 当源可能有故障时;实际上没有,不使用conv=sync,noerror;当源可能有故障时使用 GNUddrescue
  • bs=…– 大缓冲区不会耗尽我的硬盘;
  • count=…– 读取片段,例如 MBR;
  • conv=sparse– 在某些情况下缩小图像尺寸。

还有更多。此命令:

kill -s USR1 $(pidof dd)

ddI/O 统计信息打印到标准错误。我认为您无法使用 来执行此操作cat

原因如下我认为dd它是处理原始图像的自然工具。cat我认为没有必要仅仅因为某些特殊情况下没有区别就改变工具,但我看到了另一个原因(如下)。我想这些说明之所以经常使用,dd是因为它们的作者和我的想法一样。有意识地选择的能力是一种优雅合适的工具,尤其是当有更多看似同样合适的选择时。

仍然dd是一个难以正确使用且不稳定的工具。任何人有意识地选择正确工具的能力都应该包括意识到这个事实。如果你不确定是否可以dd正确使用,那么可能正确的工具为你不是dd

如果你确定你可以dd正确使用,那么请注意邓宁-克鲁格效应然后再问自己。:)


最后我承认我用过pv myimage.img | sudo tee /dev/sdb > /dev/null。我放弃了我正确的工具,但pv给了我一个进度条。除非你需要连接,否则cat什么都没有cat让你简单,并保护你免受暴躁dd带来的陷阱。仅凭这个原因,它可能你正确的工具在某些情况下,它是我的正确工具。

重要的是:每当我使用ddcat任何其他方式来完成相关任务时,它都是选择的工具,有意识的选择。

相关内容