Gil*_*il' 184
在外观上,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
是,它最出名的是其他工具可以做的事情。)
>
在 shell 中使用重定向时也会发生这种情况。>>
shell 中的重定向附加到文件的内容,或者使用tee -a
.如果您想通过在某个点之后删除所有数据来缩短文件,底层内核和 C API 通过该truncate
函数支持,但不会被任何命令行工具公开,除了dd
:
dd if=/dev/null of=/file/to/truncate seek=1 bs=123456 # truncate file to 123456 bytes
Run Code Online (Sandbox Code Playgroud)如果您想覆盖文件中间的数据,同样,这可以在底层 API 中通过打开文件进行写入而不截断(并lseek
在必要时调用以移动到所需位置),但只能dd
打开文件而无需截断或追加,或从 shell查找(更复杂的示例)。
# 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
Run Code Online (Sandbox Code Playgroud)所以……作为系统工具,dd
几乎没什么用。作为一个文本(或二进制文件)处理工具,非常有价值!
Lau*_*low 24
还没有人提到您可以使用 dd 创建稀疏文件,但truncate
也可以用于相同目的。
dd if=/dev/zero of=sparse-file bs=1 count=1 seek=10GB
Run Code Online (Sandbox Code Playgroud)
这几乎是即时的,并创建了一个可以用作环回文件的任意大文件,例如:
loop=`losetup --show -f sparse-file`
mkfs.ext4 $loop
mkdir myloop
mount $loop myloop
Run Code Online (Sandbox Code Playgroud)
好消息是它最初只使用单个磁盘空间块,然后仅根据需要增长(10GB 文件的 ext4 格式在我的系统上消耗 291 MB)。使用du
看实际多少磁盘空间使用-ls
仅报告文件可能会增长到最大尺寸。
Cal*_*leb 23
该dd
命令包含大量 cat 无法容纳的选项。也许在您的使用案例中 cat 是一个可行的替代品,但它不是 dd 替代品。
一个例子是dd
用来复制某些东西的一部分,而不是整个东西。也许您想根据设备上的已知位置从iso 映像的中间或硬盘驱动器的分区表中删除一些位。随着dd
您可以指定启动,停止和数量的选项,允许这些行动。
这些选项dd
使其对于细粒度数据操作必不可少,而cat
* 只能对整个文件对象、设备或流进行操作。
*正如 Gilles 在评论中所指出的,可以cat
与其他工具结合使用来隔离某些部分,但cat
仍然对整个对象进行操作。
XQY*_*QYZ 10
用某些东西覆盖硬盘驱动器的特定部分是一个常见的例子。例如,您可能想使用以下命令删除 MBR:
dd if=/dev/zero of=/dev/sda bs=446 count=1
Run Code Online (Sandbox Code Playgroud)
你也可以用它创建空文件(比如循环磁盘映像):
dd if=/dev/zero of=10mb.file bs=1024k count=10
Run Code Online (Sandbox Code Playgroud)
dd
对于备份硬盘驱动器或其他存储设备的引导扇区 ( dd if=/dev/sda of=boot_sector.bin bs=512 count=1
) 并随后重写它 ( dd if=boot_sector.bin of=/dev/sda
)非常有用。它对于备份加密卷的标头同样有用。
cat
可能会被扭曲到这样做,但我不会相信它在重写部分。很难cat
只读/写一定数量的字节。
这是我多年来想出的一些 dd 技巧。
如果您处于未检测到 EOF/^D/^F 的情况下,您可以使用 dd 将文本文件传输到主机。因为它会在指定数量的字节后自动停止读取。
我最近在去年的一次安全练习中使用了它,在那里我们能够在远程主机上获得非 tty shell 并需要传输文件。
事实上,我什至通过 base64 编码并使用缓慢但可靠的纯 bash base64 解码脚本制作了几个二进制文件。
dd of=textfile.txt bs=1 count=<size_of_data_in_paste_buffer>
Run Code Online (Sandbox Code Playgroud)
一个超酷的技巧是,当 dd 运行时,如果你向它发送一个 USR1 信号,它会发出它的当前状态(读取的字节数,每秒字节数..)
我写这个是为了作为任何通过标准输出发出数据的程序的纯 bash 进度过滤器。(注意:几乎任何东西都会通过 stdout 发出数据 - 对于不发出数据的程序,如果他们不使用 /dev/stdout 作为文件名对你发出警告,你可以作弊。但这个想法基本上是,每次你得到 X字节数,打印散列标记(就像打开散列模式时的老式 FTP)
(注)进度文件的东西很蹩脚,这主要是一个概念证明。如果我重做它,我只会使用一个变量。
dd bs=$BLKSZ of=${TMPFILE} 2>&1 \
| grep --line-buffered -E '[[:digit:]]* bytes' \
| awk '{ print $1 }' >> ${PROGRESS} &
while [[ $(pidof dd) -gt 1 ]]; do
# PROTIP: You can sleep partial seconds
sleep .5
# Force dd to update us on it's progress (which gets
# redirected to $PROGRESS file.
pkill -USR1 dd
local BYTES_THIS_CYCLE=$(tail -1 $PROGRESS)
local XFER_BLKS=$(((BYTES_THIS_CYCLE-BYTES_LAST_CYCLE)/BLKSZ))
if [ $XFER_BLKS -gt 0 ]; then
printf "#%0.s" $(seq 0 $XFER_BLKS)
BYTES_LAST_CYCLE=$BYTES_THIS_CYCLE
fi
done
Run Code Online (Sandbox Code Playgroud)
这是一个非常伪代码的示例,说明如何通过匿名文件句柄提供 tar 输入来获得签名的 tar 文件,而无需使用任何 tmp 文件来存储部分文件数据,从而可以无错误地提取该文件。
generate_hash() {
echo "yay!"
}
# Create a tar file, generate a hash, append it to the end
tar -cf log.tar /var/log/* 2>/dev/null
TARFILE_SIZE=$(stat -f "%z" log.tar)
SIGNATURE=$(generate_hash log.tar)
echo $SIGNATURE >>log.tar
# Then, later, extract without getting an error..
tar xvf <(dd if=$OLDPWD/log.tar bs=1 count=${TARFILE_SIZE})
Run Code Online (Sandbox Code Playgroud)
tl;dr 是:我发现 dd 非常有用。这些只是我能想到的三个例子。
小智 5
您可以重定向一些输出内容。如果您需要使用以下内容编写,它特别有用sudo
:
echo some_content | sudo dd status=none of=output.txt
Run Code Online (Sandbox Code Playgroud)
除此之外,sudo
它相当于:
echo some_content > output.txt
Run Code Online (Sandbox Code Playgroud)
或者到这个:
echo some_content | sudo tee output.txt > /dev/null
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
41021 次 |
最近记录: |