Linux / コマンド / dd - ブロック単位のデータコピーと変換

ddは、入力からデータをブロック単位で読み取り、出力に書き込みながらブロックサイズと変換方式を制御するコマンドです。ディスクイメージの作成と復元、限定された範囲のコピー、データ形式の変換に便利ですが、ofを誤って指定すると対象のディスクやファイルを即座に上書きする可能性があります。

この記事では、ifとof、bs・count・skip・seek、進行状況の表示、エラー処理と同期オプションを説明し、デバイス操作前の確認手順を強調します。

ddコマンドとは?

ddは基本的に標準入力から読み込み標準出力に書き込み、if=とof=で入力・出力を指定します。一般のコマンドと異なり、主な指定(オペランド)は名前=値形式を使用し、等号の周囲に空白を入れません。出力ファイルはconv=notruncがない場合、基本的に切り捨てられることがあります。

基本的な文法

dd [オペランド] ...

ファイル名に空白がある場合は if="source file.img" や of="copy file.img" のように値を引用符で囲みます。名前は if= と of= の値として渡すため、他のコマンドのように -- の後へ単独のファイル名を並べる形式ではありません。サポートされるオプションはディストリビューションとGNU Coreutilsのバージョンによって異なる場合があるため、dd --helpとman ddで現在のシステムの説明を確認してください。

ddの基本的な使い方

ファイルを別のファイルにコピーする

ifは入力ファイルで、ofは出力ファイルです。一般的なファイルコピーには通常cpコマンドの方が簡単ですが、ブロック制御が必要な場合にはddを使用します。

dd if=source.img of=copy.img bs=4M status=progress

固定サイズのテストファイルを作成する

/dev/zeroから読み込み、指定したブロック数だけ書き込みます。コマンドとしては指定量の0バイトを書き込むため、書き込み負荷が発生します。物理的な割り当て量は、ファイルシステムの圧縮や重複排除などにも左右されます。

dd if=/dev/zero of=test.bin bs=1M count=100 status=progress

ディスクイメージをファイルに保存する

デバイスが使用中の場合、一貫性のないイメージになる可能性があります。可能であればアンマウントするかスナップショットを使用し、読み取り対象のデバイスを正確に確認してください。

sudo dd if=/dev/sdb of=/backup/disk-sdb.img bs=16M status=progress conv=fsync

デバイスの代わりに小さなファイルでコピー結果を確認する

ddは入力(if=)と出力(of=)をバイト単位でコピーします。デバイスパスを間違えるとデータが上書きされるため、まず小さな一般ファイルで動作を理解してください。

printf 'ABC' > source.bin
dd if=source.bin of=copy.bin bs=1 status=none
cmp -s source.bin copy.bin
echo $?

出力例の 0 は、両方のファイルのバイト内容が同じであることを意味します。status=none は通常の統計や進行状況を非表示にしますが、エラー診断は表示します。デバイスイメージを扱う際は、ターゲットサイズ、マウント状況、バックアップを別々に確認する必要があります。

主なオプション

オプション 説明
if=FILE 入力ファイルやデバイスを指定してください。
of=FILE 出力ファイルやデバイスを指定します。
bs=SIZE 入力ブロックサイズと出力ブロックサイズを一緒に指定します。
count=N コピーする入力ブロック数を制限します。短い読み取りがある場合はfullblockの指定にも注意します。
skip=N 入力のブロック数(ibs、bsで指定した大きさ)だけ読み飛ばします。
seek=N 出力のブロック数(obs、bsで指定した大きさ)だけ先へ進んだ位置から書き始めます。
status=progress 定期的に転送ボリュームや進捗情報を表示します。
conv=noerror,sync 読み取りエラー後に続行して短いブロックを埋めます。復旧の目的と限界を理解する必要があります。
conv=fsync 終了前に出力データとメタデータの同期を要求します。
iflag=fullblock 短い読み取りを集めて入力ブロックを埋めるようにします。パイプ入力では重要になる場合があります。

長いオプションは意味を把握しやすく、スクリプトの確認にも役立ちます。ただし、移植性が重要なスクリプトでは対象システムがその GNU 拡張オプションをサポートしているかをまず確認してください。

実践的活用例

デバイスを識別してからイメージを復元する

復元は出力デバイスの既存パーティションとデータを上書きします。デバイス名は再起動や接続順序によって変わる場合があるので、モデル、シリアル番号、サイズおよびマウント状態を確認し、対象のファイルシステムをアンマウントしてください。

lsblk -o NAME,SIZE,MODEL,SERIAL,FSTYPE,MOUNTPOINTS
findmnt
sudo dd if=/backup/disk.img of=/dev/sdc bs=16M status=progress conv=fsync

ファイルの一部だけを抽出する

skipとcountは指定した入力ブロックサイズを基準にしています。バイト単位のオフセットが必要な場合は、インストールされているGNUのバージョンでiflag=skip_bytes,count_bytesのサポート有無を確認してください。

dd if=disk.img of=segment.bin bs=1M skip=100 count=20 status=progress

コピー結果の検証

デバイス全体を再読み込みしてハッシュ計算すると時間と負荷が大きくなりますが、重要な複製では元のものと結果のサイズ・パーティション・チェックサムを目的に応じて確認する必要があります。出力キャッシュが保存装置に反映されているかも考慮してください。

sha256sum source.img copy.img
stat -c '%s %n' source.img copy.img
sync

ddと関連コマンドの比較

コマンド・方法 主な役割 適した状況
dd ブロック単位のコピー・変換 ディスクイメージとオフセットベースの作業
cp ファイルシステムレベルの一般的コピー 一般ファイルとディレクトリのコピー
rsync 増分・リモートファイル同期 定期バックアップとネットワークコピー
ddrescue 不良メディア回復に特化したリトライ・マップファイル 読み取りエラーがある媒体から読めるデータを優先して救出する場合

使用する際の注意点

例の /dev/sdb や /dev/sdc は機器を特定するための固定名ではありません。自分で確認した対象へ置き換え、出力先を誤っていないことと、消えるデータのバックアップを確認してください。ディスク全体を扱う場合は配下のパーティションが使われていないことも確認します。小さなファイルの練習には未使用の出力名を使い、既存の出力ファイルを置き換えたくない場合は対応版の conv=excl で既存時に失敗させる方法もあります。

ifとofを入れ替えると元のデータを失う可能性があります

ofは書き込み対象です。コマンドを実行する直前にデバイス識別結果と入出力方向を再確認してください。

大きなbsが常に高速というわけではありません

デバイス、カーネルキャッシュ、作業種類によって適切なサイズは異なります。過度に大きなブロックはエラー復旧単位を増やし、メモリ使用量を増やす可能性があります。

不良ディスクの復旧には専用ツールを検討してください

conv=noerror,syncは単純なエラー継続処理機能です。再試行や中断・再開の管理が必要な復旧には、GNU ddrescueとマップファイルによる救出を検討します。マップファイルは救出済み・未処理などの領域を記録します。conv=noerror,sync では読めなかった内容を再現できず、短い入力の埋め合わせやブロック位置にも注意が必要です。

FAQ

ddでのifとofは何ですか?

ifは読み取り入力、ofは上書き出力です。デバイス作業では方向を変えると重大なデータ損失が発生する可能性があります。

進行状況を確認するにはどうすればよいですか?

GNU ddではstatus=progressを追加します。最終統計と実際の保存完了状況は別途確認してください。

USBブートイメージを書く際にパーティションのパスを指定しますか?

一般的な全ディスクイメージはパーティションではなく、対象ディスクデバイス全体に書き込むことが多いですが、イメージ形式の指示に従う必要があります。デバイス選択は必ず検証してください。

読み取りエラーのあるディスクもddで復旧できますか?

一部のデータは読み取れますが、不良領域の再試行や中断・再開が必要な復旧には、GNU ddrescueのような専用ツールが一般的により適しています。

参考資料