dd 需要将每个输入块放大/填充到双倍大小

dd 需要将每个输入块放大/填充到双倍大小

我发现了一些声称这一点的示例,但我无法设法让 dd 将具有给定块大小的文件转换为该块大小的两倍。

dd if=disk256bytesectors.img of=disk512bytesectors.img cbs=256 ibs=512 obs=512 conv=sync

我的磁盘 img 大小为 10 MB,我原本期待 20 MB 的新映像,但没有。

因此,我需要将每个 256 字节块转换为 512 字节块,每个 512 字节块的后半部分为空、零、空格或任何内容。

dd 手动状态 conv=sync

在转换和输出之前,用空字节将任何短于 ibs 的输入块填充到该大小。

但输入块永远不会比它本身短?!?!那么这意味着什么呢?

无论如何我该怎么做呢?

答案1

当您为命令指定时,您也许可以使用socat使用 Unix 域套接字的 which 。exec:这可以由数据报 ( type=2) 类型组成,以确保 dd 的输入只有 256 字节。

例如,对于每个数据报 2 个字节 ( -b2) 填充为 4 ( bs=4):

$ echo abcdefx | socat -u -b2 - exec:'dd bs=4 conv=sync',type=2 | od -c   
0000000   a   b  \0  \0   c   d  \0  \0   e   f  \0  \0   x  \n  \0  \0

请注意,上面对 stdin 的管道的使用socat仅用于此测试。通常,您应该直接在标准输入上提供输入文件,以便socat读取所需-b大小(即<file socat -u ...)的整个“块”。

答案2

我不会dd使用二进制编辑器,

bbe在 Ubuntu 的存储库中可用universe,并且可以使用

sudo apt install bbe

我认为大多数 Linux 发行版都可以使用它。有关命令行的详细信息,请参阅man bbe下面的脚本。

#!/bin/bash

if ! test -f 256dots
then
 for i in {1..256};do echo -n '.';done > 256dots
fi

filler=$(cat 256dots)

bbe -b :256 -e "A $filler" d256.img > d512.img
  • 首先创建一个文件,用于用点填充 shell 变量(如果您愿意,可以修改它)。
  • 从输入文件中读取接下来的 256 字节块并附加填充符。
  • 然后将其全部写入输出文件,每个 256 字节的输入块写入 512 字节。

这个 shellscript 当然可以改进,但它对我来说适用于以下文件名

  • 输入文件:d256.img

  • 输出文件:d512.img

答案3

主要问题

因此,我需要将每个 256 字节块转换为 512 字节块,每个 512 字节块的后半部分为空、零、空格或任何内容。

我认为dd做不到这一点。

bbe是“sed类似二进制文件的编辑器”。在 Debian 中,它位于bbe软件包中。

运行bbe,指定块长度为 256。在下面的代码中,该$(…)部分负责生成如下所示的脚本:A \0\0\0\0…。将会有 256 次出场\0。该脚本的意思是“在每个块之后附加 256 个 NULL 字节”。

<disk256bytesectors.img bbe -b :256 -e "$(
   printf 'A '; yes '\0' | head -n 256 | tr -d '\n'
)" >disk512bytesectors.img

这样,输入中的每个 256 字节块将增长到输出中的 512 字节。


附带问题关于dd

conv=sync[...]但是输入块永远不会比它本身短?!?!那么这意味着什么呢?

这意味着如果dd读取次数少于ibs单个读取操作(例子) 然后conv=sync它会附加 NULL 字节。

答案4

dd还可以使用 todd提供填充输入来填充输入。例如,假设大小为 2 和 4,而不是 256 和 512:

dd bs=2 count=1 |
dd bs=4 count=1 conv=sync

第一个dd只会读取 2 个字节,一次,第二个dd将读取 2 个字节,然后将其填充到 4 个字节,一次。

您只需要在循环中执行此操作,效率有些低,直到没有更多数据(当dd报告时0 bytes copied:)。例如,对于输入字符串 abcdefx:

#!/bin/bash
echo abcdefx | ( exec 3>&1
while   log=$(dd bs=2 count=1 status=none |
              dd bs=4 count=1 conv=sync 2>&1 1>&3)
        ! [[ "$log" =~ [^0-9]'0 bytes copied' ]]
do :
done ) | od -c

结果是

0000000   a   b  \0  \0   c   d  \0  \0   e   f  \0  \0   x  \n  \0  \0

相关内容