将图像文件写入磁盘或 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. 超越简单案例
想象一下一位制作厨房桌子的木匠。大多数桌子的桌面都是矩形的;菱形的桌子很少见。有一张桌面是方形的桌子需要制作。方形是菱形,也是矩形。木匠会使用适用于罕见的菱形桌子的方法吗?还是适用于常见的矩形桌子?这两种方法都应该适用于方形桌子,尽管他每个工作日都制作矩形,所以改变方法毫无意义。
回到cat
和dd
。在我看来(和我的实践),几乎不需要连接多个图像以将它们全部写入块设备。这肯定是的工作cat
。该工具可以做更多的事情,但你不想要它:选项以文本文件为目标,因此当与图像文件一起使用时,它们可以使您的二进制数据无效。
dd
现在,当我从设备读取或写入时,提供的选项通常对我有用:
实际上没有,不使用conv=noerror
– 当源可能有故障时;conv=sync,noerror
;当源可能有故障时使用 GNUddrescue
;bs=…
– 大缓冲区不会耗尽我的硬盘;count=…
– 读取片段,例如 MBR;conv=sparse
– 在某些情况下缩小图像尺寸。
还有更多。此命令:
kill -s USR1 $(pidof dd)
将dd
I/O 统计信息打印到标准错误。我认为您无法使用 来执行此操作cat
。
原因如下我认为dd
它是处理原始图像的自然工具。cat
我认为没有必要仅仅因为某些特殊情况下没有区别就改变工具,但我看到了另一个原因(如下)。我想这些说明之所以经常使用,dd
是因为它们的作者和我的想法一样。有意识地选择的能力是一种优雅合适的工具,尤其是当有更多看似同样合适的选择时。
仍然dd
是一个难以正确使用且不稳定的工具。任何人有意识地选择正确工具的能力都应该包括意识到这个事实。如果你不确定是否可以dd
正确使用,那么可能正确的工具为你不是dd
。
如果你确定你可以dd
正确使用,那么请注意邓宁-克鲁格效应然后再问自己。:)
最后我承认我用过pv myimage.img | sudo tee /dev/sdb > /dev/null
。我放弃了我正确的工具,但pv
给了我一个进度条。除非你需要连接,否则。cat
什么都没有cat
让你简单,并保护你免受暴躁dd
带来的陷阱。仅凭这个原因,它可能你正确的工具。在某些情况下,它是我的正确工具。
重要的是:每当我使用dd
或cat
任何其他方式来完成相关任务时,它都是选择的工具,有意识的选择。