「Dd」の版間の差分
細 (→パーティションの複製: 修正) |
(→Troubleshooting: 同期) |
||
152行目: | 152行目: | ||
== Troubleshooting == |
== Troubleshooting == |
||
+ | {{Style|The troubleshooting section currently only hold one subsection that describes the logic of dd's {{ic|count}} option. Merge this into a previous section for a better overall reading experience in linear order.}} |
||
+ | === Partial read: copied data is smaller than requested === |
||
+ | Files created with ''dd'' can end up with a smaller size than requested if a full input block is not available for various reasons (i.e. the underlying {{man|2|read}} system call returns early.) This can happen when reading from a {{man|7|pipe}}, or when reading a device file like {{ic|/dev/urandom}} and {{ic|/dev/random}} (e.g. due to [https://unix.stackexchange.com/a/178957#178957 hardcoded limitation of underlying kernel device driver] or insufficient entropy.), in conjunction of {{ic|1=count=''n''}} option where {{ic|''n''}} is the number of input block(s) to copy to output. |
||
− | === Partial read === |
||
+ | It is possible, but not guaranteed, that ''dd'' will warn you about such kind of issue: |
||
− | Files created with ''dd'' can end up with a smaller size than requested if a full input block is not available and the {{man|2|read}} system call returns early. This can happen when reading from a {{man|7|pipe}} or when reading from {{ic|/dev/random}} and there is not enough entropy[https://unix.stackexchange.com/a/121888], or from {{ic|/dev/urandom}} when reading more than 32 MiB[https://unix.stackexchange.com/a/178957]. |
||
− | |||
− | It is possible, but not guaranteed, that ''dd'' will warn you about the issue: |
||
dd: warning: partial read (''X'' bytes); suggest iflag=fullblock |
dd: warning: partial read (''X'' bytes); suggest iflag=fullblock |
||
− | The solution is to do as the warning says |
+ | The solution is to do as the warning says, add {{ic|1=iflag=fullblock}} option in addition to the input file option to the ''dd'' command. For example, to create a new file filled up with random data in total length of 40 megabytes: |
+ | |||
+ | $ dd if=/dev/urandom of=new-file-filled-by-urandom.bin bs=40M count=1 iflag=fullblock |
||
+ | {{Note|When reading from a pipe or a special device file like we just mentioned below for copying a portion of file in a fixed length with {{ic|1=count=''n''}} option being specified, it is suggested to, or always strongly recommended to add the {{ic|1=iflag=fullblock}} option to the ''dd'' command if in case of [[Securely wipe disk|wiping]] a [[#Remove bootloader|portion of device]] or [[Securely wipe disk/Tips and tricks#Wipe a single file|file]].}} |
||
− | $ dd if=/dev/random of=bigsecret.img bs=1K count=1 iflag=fullblock |
||
− | $ dd if=/dev/urandom of=bigsecret.img bs=40M count=1 iflag=fullblock |
||
+ | When reading from a pipe, [https://unix.stackexchange.com/questions/556016/cat-dd-pipe-causes-partial-reads-without-iflag-fullblock-why-truncated-to-128 an alternative] to {{ic|1=iflag=fullblock}} is to limit {{ic|bs}} to the {{ic|PIPE_BUF}} constant value as defined in [https://elixir.bootlin.com/linux/latest/A/ident/PIPE_BUF {{ic|linux/limits.h}}] to make the {{man|7|pipe}} I/O atomic. For example, to prepare a text file filled up will random alphanumeric string in total length of 5 megabytes: |
||
− | {{Note|It is strongly recommended to always add the {{ic|1=iflag=fullblock}} option to the ''dd'' command when the input file is {{ic|/dev/random}} or {{ic|/dev/urandom}}.}} |
||
+ | $ LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | dd of=passtext-5m.txt bs='''4k''' count=1280 |
||
− | An alternative for {{ic|/dev/urandom}} is to specify a block size smaller than 32 MiB, but a larger copy count. For example: |
||
+ | Since the output file is not a pipe, one may prefer to use {{ic|1=ibs}} and {{ic|1=obs}} options to set block size separately for the (''input'') pipe and the (''output'') on-disk file. For example, to set a more efficient block size for output file: |
||
− | $ dd if=/dev/urandom of=bigsecret.img bs=1M count=40 |
||
+ | $ LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | dd of=passtext-5m.txt ibs=4k obs=''64k'' count=1280 |
||
− | When reading from a pipe, an alternative to {{ic|1=iflag=fullblock}} is to limit {{ic|bs}} to the {{ic|PIPE_BUF}} constant value, defined in {{ic|/usr/include/linux/limits.h}} [https://unix.stackexchange.com/questions/556016/cat-dd-pipe-causes-partial-reads-without-iflag-fullblock-why-truncated-to-128]. For example: |
||
+ | {{tip|In some circumstances, merely keep the the output block size the same the value as input block size with a value defined by {{ic|PIPE_BUF}} constant may already be optimal.}} |
||
− | $ cat input.img | dd of=output.img bs=4k count=100 |
2022年10月7日 (金) 12:56時点における版
dd はファイルの変換とコピーを主な目的とする コアユーティリティ です。
cp と同様にデフォルトでは dd はファイルのビットごとのコピーを作成しますが、低レベルの I/O フロー制御機能を備えています。
詳細は、dd(1) またはフルドキュメントを参照してください。
目次
インストール
dd は GNU coreutils の一部です。このパッケージ内の他のユーティリティについては、Core utilities を参照してください。
ディスクの複製と復元
dd コマンドはシンプルでありながら多機能で強力なツールです。ファイルシステムの種類や OS に関係なく、コピー元からコピー先へブロック単位でコピーすることができます。ライブ CD のようなライブ環境から dd を使用するのが便利です。
パーティションの複製
物理ディスク /dev/sda
のパーティション 1 から、物理ディスク /dev/sdb
のパーティション 1 へ:
# dd if=/dev/sda1 of=/dev/sdb1 bs=64K conv=noerror,sync status=progress
ハードディスク全体の複製
物理ディスク /dev/sda
から物理ディスク /dev/sdb
へ:
From physical disk /dev/sda
to physical disk /dev/sdb
:
# dd if=/dev/sda of=/dev/sdb bs=64K conv=noerror,sync status=progress
MBR (つまりブートローダ)、すべてのパーティション、UUID、データを含むドライブ全体のクローンを作成します。
bs=
はブロックサイズを設定します。デフォルトは512バイトで、これは1980年代前半以降のハードドライブの「古典」的なブロックサイズですが、最も便利なものではありません。64KBや128KBなど、より大きな値を使用してください。また、「ブロックサイズ」だけでなく、読み取りエラーの伝搬にも影響を与えるため、以下の警告をお読みください。詳細は、[1] と [2] を参照して、自分の使用例に最適な bs 値を見付けてください。noerror
はすべての読み取りエラーを無視して操作を続けるように dd に指示します。dd のデフォルトの動作は、いかなるエラーでも停止します。sync
は読み込みエラーがあった場合、入力ブロックをゼロで埋め、データのオフセットは同期されたままになります。status=progress
は、操作がいつ完了するかを推測するために使用できる転送統計を表示します。
dd ユーティリティには、技術的に「入力ブロックサイズ」(IBS)と「出力ブロックサイズ」(OBS)があります。bs
を設定すると、実質的に IBS と OBS の両方を設定することになります。通常、ブロックサイズが例えば 1MiB の場合、dd は 1024×1024 バイトを読み込み、同じバイト数を書き込みます。しかし、読み取りエラーが発生すると、事態はおかしくなります。多くの人は、noerror,sync オプションを使うと、dd が「読み込みエラーをゼロで埋める」と思っているようですが、そうではありません。dd はドキュメントによると、読み込み完了後に OBS から IBS のサイズを埋める、つまりブロックの最後にゼロを追加するのです。つまり、ディスクの場合、512 バイトの読み取りエラーが読み取りの最初に1回発生しただけで、事実上 1MB 全体がめちゃくちゃになってしまうのです: 12ERROR89 は 120000089 ではなく 128900000 となります。
ディスクにエラーがないことが確認できれば、ブロックサイズを大きくしてコピーを進めることができ、コピーの速度が数倍向上します。例えば、Celeron 2.7GHz のシステムで、bs を 512 から 64K に変更すると、コピー速度が 35MB/s から 120MB/s になります。ただし、コピー元のディスクで発生した読み取りエラーは、コピー先のディスクではブロックエラーとして発生することに注意してください。
パーティションテーブルのバックアップ
fdisk#パーティションテーブルのバックアップとリストア または gdisk#パーティションテーブルのバックアップとリストア を参照。
Create disk image
Boot from a live medium and make sure no partitions are mounted from the source hard drive.
Then mount the external hard drive and backup the drive:
# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c > /path/to/backup.img.gz
If necessary (e.g. when the resulting files will be stored on a FAT32 file system) split the disk image into multiple parts (see also split(1)):
# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c | split -a3 -b2G - /path/to/backup.img.gz
If there is not enough disk space locally, you may send the image through ssh:
# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c | ssh user@local dd of=backup.img.gz
Finally, save extra information about the drive geometry necessary in order to interpret the partition table stored within the image. The most important of which is the cylinder size.
# fdisk -l /dev/sda > /path/to/list_fdisk.info
システムの復元
システムを復元するには:
# gunzip -c /path/to/backup.img.gz | dd of=/dev/sda
イメージが分割されている場合は、代わりに以下を使用してください:
# cat /path/to/backup.img.gz* | gunzip -c | dd of=/dev/sda
バイナリーファイルのパッチ適用
ファイルのオフセット 0x123AB
を16進数列 FF C0 14
に置き換えたい場合は次のコマンドラインで実行できます:
# printf '\xff\xc0\x14' | dd seek=$((0x123AB)) conv=notrunc bs=1 of=/path/to/file
MBR のバックアップと復元
Before making changes to a disk, you may want to backup the partition table and partition scheme of the drive. You can also use a backup to copy the same partition layout to numerous drives.
The MBR is stored in the the first 512 bytes of the disk. It consists of 4 parts:
- The first 440 bytes contain the bootstrap code (boot loader).
- The next 6 bytes contain the disk signature.
- The next 64 bytes contain the partition table (4 entries of 16 bytes each, one entry for each primary partition).
- The last 2 bytes contain a boot signature.
To save the MBR as mbr_file.img
:
# dd if=/dev/sdX of=/path/to/mbr_file.img bs=512 count=1
You can also extract the MBR from a full dd disk image:
# dd if=/path/to/disk.img of=/path/to/mbr_file.img bs=512 count=1
To restore (be careful, this destroys the existing partition table and with it access to all data on the disk):
# dd if=/path/to/mbr_file.img of=/dev/sdX bs=512 count=1
If you only want to restore the boot loader, but not the primary partition table entries, just restore the first 440 bytes of the MBR:
# dd if=/path/to/mbr_file.img of=/dev/sdX bs=440 count=1
To restore only the partition table, one must use:
# dd if=/path/to/mbr_file.img of=/dev/sdX bs=1 skip=446 count=64
ブートローダーの削除
MBR ブートスラップコードを消去するには(別のオペレーティングシステムを完全に再インストールする必要がある場合に役立つ場合があります)、最初の440バイトのみをゼロにする必要があります。
# dd if=/dev/zero of=/dev/sdX bs=440 count=1
Troubleshooting
Partial read: copied data is smaller than requested
Files created with dd can end up with a smaller size than requested if a full input block is not available for various reasons (i.e. the underlying read(2) system call returns early.) This can happen when reading from a pipe(7), or when reading a device file like /dev/urandom
and /dev/random
(e.g. due to hardcoded limitation of underlying kernel device driver or insufficient entropy.), in conjunction of count=n
option where n
is the number of input block(s) to copy to output.
It is possible, but not guaranteed, that dd will warn you about such kind of issue:
dd: warning: partial read (X bytes); suggest iflag=fullblock
The solution is to do as the warning says, add iflag=fullblock
option in addition to the input file option to the dd command. For example, to create a new file filled up with random data in total length of 40 megabytes:
$ dd if=/dev/urandom of=new-file-filled-by-urandom.bin bs=40M count=1 iflag=fullblock
When reading from a pipe, an alternative to iflag=fullblock
is to limit bs
to the PIPE_BUF
constant value as defined in linux/limits.h
to make the pipe(7) I/O atomic. For example, to prepare a text file filled up will random alphanumeric string in total length of 5 megabytes:
$ LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | dd of=passtext-5m.txt bs=4k count=1280
Since the output file is not a pipe, one may prefer to use ibs
and obs
options to set block size separately for the (input) pipe and the (output) on-disk file. For example, to set a more efficient block size for output file:
$ LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | dd of=passtext-5m.txt ibs=4k obs=64k count=1280