cat
和dd
一样多,它实际上比dd
更快。但是,在这些日子里,dd
可以做某些事情吗? (在这里,我认为不到20%的性能差异是不相关的。)#1 楼
从外观上看,dd
是IBM操作系统中的一种工具,它保留了其外观(参数传递),该工具执行一些很少使用的功能(例如EBCDIC到ASCII转换或字节序反转……如今不常见)。 br /> 我以前以为
dd
可以在同一磁盘上复制大块数据更快(由于更有效地使用了缓冲),但这至少在当今的Linux系统上不是这样。 br /> 我认为
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
以其他工具可以做的事情而闻名。)即擦除其内容并从头开始。当您在外壳中也使用>
重定向时,就会发生这种情况。您可以在外壳中使用
>>
重定向或使用tee -a
重定向将文件内容附加到文件的内容。如果要通过删除某个点之后的所有数据来缩短文件,则底层内核和C API通过
truncate
函数支持此功能,但除dd
之外,任何命令行工具都没有公开此功能: dd if=/dev/null of=/file/to/truncate seek=1 bs=123456 # truncate file to 123456 bytes
如果您想覆盖文件中间的数据,同样,在底层API中,可以通过打开文件而无需截断(并调用
lseek
移动到(如果需要,可以将其放在所需的位置),但只有dd
可以打开文件而不会截断或追加或从外壳中查找(更复杂的示例)。 >所以……作为系统工具,dd
几乎没有用。作为文本(或二进制文件)处理工具,它非常有价值!评论
接受,是因为我认为它可以解释其他答案的要点(从dd中删除并寻求可用性)。
– kizzx2
2011年5月4日13:01
另一特殊用途:dd可以从不可搜索的文件描述符读取二进制数据,而不会由于stdio缓冲而潜在地破坏未读取的数据。参见此处的示例:etalabs.net/sh_tricks.html
–R .. GitHub停止帮助ICE
2011年5月7日,2:11
@R ..:是的。在GNU coreutils 6.10中,head -c N调用read,并且永远不会超过N。在NetBSD 5.1中,head -c调用getc。在FreeBSD 7.4中,head -c调用fread。
–吉尔斯'所以-不再是邪恶的'
2011年5月7日,12:29
Coreutils dd还向外壳脚本公开了O_DIRECT(等),我认为这也是唯一的。
–德罗伯特
17年8月2日在16:11
Coreutils truncate允许截断或扩展文件,从而消除了dd的另一种用法。
– dcoles
18年11月17日在21:14
#2 楼
还没有人提到可以使用dd创建稀疏文件,尽管truncate
也可以用于相同的目的。dd if=/dev/zero of=sparse-file bs=1 count=1 seek=10GB
可以用作环回文件的任意大文件,例如:根据需要(10GB文件的ext4格式在我的系统上消耗291 MB)。使用
du
查看实际使用了多少磁盘空间-ls
仅报告文件可能增长到的最大大小。评论
ls -ls显示稀疏大小。
– jmtd
2011年5月7日晚上10:58
您的命令将无用的字节写入文件。 dd of =稀疏文件bs = 1 count = 0 seek = 10G相当于截断-s 10GB稀疏文件。令人困惑的是,截断和dd对GB与G的解释完全相反。
–frostschutz
13年2月8日在2:49
@frostschutz:男子dd说:MB = 1000 * 1000,M = 1024 * 1024,依此类推。截断的人说:MB 1000 * 1000,M 1024 * 1024,所以没有区别。我同时使用dd和GNU coreutils中的截断。您也应该这样做! :-)
–erik
13年6月6日在9:20
@erik:感谢您的纠正。如果最近没有更改,我必须以某种方式将其与其他内容混淆。
–frostschutz
2013年6月6日16:05
#3 楼
dd
命令包含cat不能容纳的很多选项。也许在您的使用情况下,cat是一个可行的替代品,但它不是dd的替代品。也许您想根据设备上的已知位置从iso映像的中间部分或硬盘驱动器的分区表中提取一些位。使用dd
,您可以指定允许执行这些操作的开始,停止和数量选项。 *正如Gilles在评论中指出的那样,可以将
dd
与其他工具结合起来以隔离某物的某些部分,但是dd
仍然可以在整个对象上运行。评论
dd实际上与低级设备无关,它需要/ dev中的其他条目。您可以使用cat复制整个分区,或使用tail + c复制部分分区$(($ start + 1))| head -c $ count。
–吉尔斯'所以-不再是邪恶的'
2011年5月3日15:18
当然。 ;-)当我将1.6TB磁盘映像输入cat中时|头尾巴取回磁盘旋转的最后几MB,将把月亮吸近地球。
–卡莱布
2011年5月3日17:01
@Gilles对不起,我的意思是要承认我对“低级”一词的用法不是很好,尽管我指的是设备而非设备上的数据。也许“微调数据操纵”会比“操纵低水平数据”更好。
–卡莱布
2011年5月4日13:09
#4 楼
一个常见的例子是覆盖硬盘驱动器的特定段。例如,您可能想使用以下命令删除MBR:dd if=/dev/zero of=/dev/sda bs=446 count=1
评论
顺便说一句,第二个命令是我知道用完10MB最快的方法
–凯文M
2011年5月3日14:44
@Kevin:比头-c还快吗?请分享一个基准!
–吉尔斯'所以-不再是邪恶的'
2011年5月3日15:15
#5 楼
dd
对于备份硬盘驱动器或其他存储设备的引导扇区(dd if=/dev/sda of=boot_sector.bin bs=512 count=1
),然后在以后对其进行重写(dd if=boot_sector.bin of=/dev/sda
)非常有用。同样,它对于备份加密卷的标头很有用。很难让cat
只读/写一定数量的字节。#6 楼
最近,在我的Linux历史记录中,我第一次有理由克隆了多个100GB的分区(参见cp -ar
或rsync
,它们为我提供了很多服务)。当然,我转向dd
,因为大家都知道这就是您使用的...并且对性能感到震惊。不久之后,经过一番谷歌搜索,我找到了ddrescue
,我已经使用了几次,并且表现出色(比dd快得多)。评论
ddrescue非常有用,特别是对于从故障磁盘中获取数据的情况。
–ryenus
16-4-6在2:39
为了获得dd的良好性能,您必须设置块大小。例如bs = 1M。
–罗杰·达尔(Roger Dahl)
19/12/20在21:14
#7 楼
这是我多年来提出的一些dd技巧。.在不友好的tty或非交互式模式bash上剪切粘贴
在未检测到EOF / ^ D / ^ F的情况下,可以使用dd将文本文件传输到主机。因为它将在指定的字节数后自动停止读取。
我是在去年的一次安全演习中使用此软件的,当时我们能够在远程主机上获取非tty shell,并且需要在其中传输文件。事实上,我什至还通过base64编码并使用了缓慢但可靠的纯bash base64解码脚本对了几个二进制文件。
在dd运行时,如果向其发送USR1信号,它将发出其当前状态(读取的字节,每秒的字节数。)
通用吞吐量状态过滤器编写此代码可以用作任何通过stdout发射数据的程序的纯bash进度过滤器。 (注意:几乎所有东西都会通过stdout发出数据-对于不这样做的程序,如果不使用/ dev / stdout作为文件名,您可以欺骗它们,但实际上,每次输入X字节数,打印哈希标记(如启用了哈希模式的老式FTP一样)
(注意)进度文件很la脚,这主要是概念证明。我只需要使用一个变量。如何通过一个匿名文件句柄提供tar输入,而无需使用任何tmp文件来存储部分文件数据,就可以无误地提取签名的tar文件的方法。
dd of=textfile.txt bs=1 count=<size_of_data_in_paste_buffer>
/> tl; dr是:我发现dd非常有用。这些只是我想到的三个例子。#8 楼
您可以重定向一些输出内容。如果您需要使用sudo
进行编写,这将特别有用: />或对此:echo some_content | sudo dd status=none of=output.txt
评论
好点子。有关将stdout重定向到您没有写许可权的文件的更多信息
–StéphaneChazelas
18年3月13日在13:18
评论
有关一个具体示例,请参见此SO问题。