Answers:
为什么第二个命令输出不同的值?
由于历史原因,dd
被认为x
是乘法运算符。因此0x3
计算为0。
可以将skip | seek偏移量作为十六进制值传递给dd吗?
据我所知,不是直接的。除了使用运算符进行乘法运算外x
,您还可以在任何数字后缀上加上b
“乘以512”(0x200)和K
“乘以1024”(0x400)。与GNU DD也可以使用后缀M
,G
,T
,P
,E
,Z
和Y
对乘以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))
$((...))
来不会有任何改变。我唯一能想到引号在什么地方起作用的情况是,如果您有类似的操作,IFS=4
但这会引起其他各种混乱。
$((...))
。POSIX很清楚,的扩展$((...))
会受到分词的影响。split + glob运算符使列表上下文中未引用任何命令/算术/变量扩展。如果您不使用不需要/不需要的split + glob运算符,并且每次需要该split + glob运算符时都设置IFS,则将IFS = 4设置不会引起各种问题。
IFS
内容包括数字,而我不相信我曾经做过,那么您将需要引用。据推测,如果这样做的话,人们会意识到这一需求,因为这几乎不可能随便做。或者,至少,这不是我可能要做的事情。我不是要为你说话。
我知道这是一个旧线程,但是问题仍然像从前一样重要,尤其是当像我这样的白痴去无意中从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编辑器现在可以相当优雅地处理二进制内容,因此您可以检查临时文件并根据需要调整其形状。
$((...))
是POSIX算术扩展,它根本不是bash专用的,您不必bash
使用它,任何POSIX shell都可以使用。但是请注意,在包括在内的许多shell中bash
,它都会进行分词,因此应加引号。