将dd skip | seek偏移量传递为十六进制


11
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=3 2> /dev/null
d
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=0x3 2> /dev/null
f

为什么第二个命令输出不同的值?

可以将skip | seek偏移量传递dd为十六进制值吗?

Answers:


18

为什么第二个命令输出不同的值?

由于历史原因,dd被认为x是乘法运算符。因此0x3计算为0。

可以将skip | seek偏移量作为十六进制值传递给dd吗?

据我所知,不是直接的。除了使用运算符进行乘法运算外x,您还可以在任何数字后缀上加上b“乘以512”(0x200)和K“乘以1024”(0x400)。与GNU DD也可以使用后缀MGTPEZY对乘以2的意思是20的分别的功率,30%,40%,50,60,70,80或90,并且可以上使用或小写除为b后缀。(还有许多其他可能的后缀。例如,EB表示“乘以10 18 ”和PiB表示“乘以2 50 ”。有关info coreutils "block size"更多信息,如果您安装了GNU。)

您可能会发现上述奥秘,过时和令人讨厌的地方。不用担心:您并不孤单。幸运的是,您可以完全忽略所有内容,而使用外壳程序的算术替换(bash和其他符合Posix的外壳程序以及某些非Posix外壳程序都可以使用)。Shell确实可以理解十六进制数,并且它允许以常规方式编写的所有算术运算符。您只需要在表达式周围加上$((...))

# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))

请注意,这$((...))是POSIX算术扩展,它根本不是bash专用的,您不必bash使用它,任何POSIX shell都可以使用。但是请注意,在包括在内的许多shell中bash,它都会进行分词,因此应加引号。
斯特凡Chazelas

@StephaneChazelas:是的,不是bash特有的。但是,它不需要引号。(Posix:“表达式应被视为双引号,除非对表达式内部的双引号不作特殊处理。”)如果表达式中包含变量,且其值包含分隔符,那将不是一个有效的数字;用引号引起$((...))来不会有任何改变。我唯一能想到引号在什么地方起作用的情况是,如果您有类似的操作,IFS=4但这会引起其他各种混乱。
rici

您引用的部分是关于内部内容的$((...))POSIX很清楚,的扩展$((...))会受到分词的影响。split + glob运算符使列表上下文中未引用任何命令/算术/变量扩展。如果您不使用不需要/不需要的split + glob运算符,并且每次需要该split + glob运算符时都设置IFS,则将IFS = 4设置不会引起各种问题。
斯特凡Chazelas

@StephaneChazelas:是的,数字结果会进行单词拆分。但这是一个整数。如果您设置的IFS内容包括数字,而我不相信我曾经做过,那么您将需要引用。据推测,如果这样做的话,人们会意识到这一需求,因为这几乎不可能随便做。或者,至少,这不是我可能要做的事情。我不是要为你说话。
rici

1
@ogurets:您使用的是什么外壳?(请包括版本)。
rici

0

我知道这是一个旧线程,但是问题仍然像从前一样重要,尤其是当像我这样的白痴去无意中从bash历史记录中撤回并从'bash历史记录中提取了一个'cp fileA fileB'时,fileB尚未签入到git中。一个通宵的时间,然后包含几个小时的编码:-/

由于此线程中的概念,我能够完全恢复丢失的文件,但是我在具有32Gb磁盘和很少RAM(运行Ubuntu 18.04)的远程虚拟专用服务器上丢失了我的文件,并且所有我的attemtps都使用“ grep”作为以上将很快死于“内存不足”

在我的情况下,它是hexdump -C /dev/sdX1 | grep 'shortString'这拯救了我。与grep不同,它仅显示十六进制的非常讨厌的ASCII表示形式,因此仅寻找短的唯一字符串并记住即使可以包装也很重要。一旦它输出了一个匹配的十六进制地址,我就能以与上面类似的方式使用'dd',除了我发现它似乎默认为4096的块大小,所以我不仅必须将十六进制字节地址转换为十进制,但将其除以4096以将其缩放为dd的skip参数的4k块-无奈地,如果此数字对于dd太大,则错误消息看起来像是在抱怨skip=无效,而不是传递给它的数字。

对添加了有关使用bash和$((0xabcd))easyty obation hex-> dec转换的技巧的人表示敬意:-)

只是我的最后一句话-就我而言,同一个文件有多个副本,而且都非常接近。但是从hexdump报告的最高地址中减去最低地址后,我能够识别出包含所有可能副本的〜5MB区域,这意味着我可以将dd定位为最低地址并将整个区域提取到临时文件中。Vim编辑器现在可以相当优雅地处理二进制内容,因此您可以检查临时文件并根据需要调整其形状。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.