将 dd Skip|Seek 偏移量作为十六进制传递

将 dd Skip|Seek 偏移量作为十六进制传递
# 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作为十六进制值传递?

答案1

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

由于历史原因,dd被认为x是乘法运算符。所以0x3评估为0。

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

据我所知,不是直接的。除了使用运算符 进行乘法之外x,您还可以在任何数字后添加b表示“乘以 512”(0x200) 和 表示K“乘以 1024”(0x400)。使用 GNU dd,您还可以使用后缀M, G, T, P, E,ZY分别表示乘以 2 的 20、30、40、50、60、70、80 或 90 次方,并且可以使用大写或小写,除了为b后缀。 (还有许多其他可能的后缀。例如,EB表示“乘以 10 18 ”,PiB表示“乘以 2 50 ”。info coreutils "block size"如果您安装了 GNU,请参阅 参考资料 了解更多信息。)

你可能会发现上面的内容晦涩难懂、不合时宜、令人讨厌甚至荒谬。不用担心:你并不孤单。幸运的是,您可以完全忽略它并使用 shell 的算术替换(bash 和其他符合 Posix 的 shell 以及一些非 Posix shell 都可以工作)。 shell 确实理解十六进制数,并且它允许以正常方式编写的各种算术运算符。您只需要用以下内容包围表达式$((...))

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

答案2

我知道这是一个旧线程,但问题仍然与以往一样相关,特别是当像我这样的白痴在 fileB 尚未签入 git not backed 时无意中回忆并执行 bash 历史记录中的“cp fileA fileB”时通宵之后,包含几个小时的编码:-/

感谢这个线程中的概念,我能够完全恢复我丢失的文件,但是我在一个具有 32Gb 磁盘和很少 RAM(运行 Ubuntu 18.04)的远程虚拟专用服务器上丢失了我的文件,并且我所有的尝试都使用“grep”作为上面的内容很快就会因“内存不足”而死掉

就我而言,它hexdump -C /dev/sdX1 | grep 'shortString'拯救了我。与 grep 不同,它仅显示十六进制的非常狭窄的 ASCII 表示形式,因此仅查找简短的唯一字符串至关重要,并且请记住,即使该字符串也可以被换行。一旦它输出了一些匹配的十六进制地址,我就能够以与上面类似的方式使用“dd”,除了我发现它似乎默认为 4096 的块大小,所以我不仅必须将十六进制字节地址转换为十进制,但将其除以 4096,以将其缩放为 dd 的跳过参数的 4k 块 - 无济于事,如果这个数字对于 dd 来说太大,则错误消息看起来像是在抱怨skip=无效而不是传递给它的数字。

感谢那些添加了有关使用 bash$((0xabcd))轻松获取十六进制->十进制转换的提示的人们:-)

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

相关内容