[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

11.2 dd: ファイルの変換とコピー

dd はファイルをコピーする (デフォルトでは、標準入力から標準出力へコピーする)。 その際、入出力のブロックサイズを変更することができる。 また、データ形式の変換を行いつつコピーすることもできる。

書式:

 
dd [operand]…
dd option

指定できるオプションは、‘--help’ と ‘--version’ だけである。 See section 共通オプション. dd では、以下のオペランドが使える。 オペランドの書式の元になったのは、OS/360 の JCL (Job Control Language) の DD 文 (Data Definition statement) である。

if=file

標準入力の代わりに、file から読み込む。

of=file

標準出力の代わりに、file に書き出す。‘conv=notrunc’ が指定されていない場合、dd は、出力を開始する前に、file を 0 バイトに (あるいは、‘seek=’ で指定されたサイズに) 短縮する。

ibs=bytes

入力ブロックサイズを bytes にする。dd が 1 ブロック bytes バイトで読み込みを行うようになる。デフォルトは 512 バイトである。

obs=bytes

出力ブロックサイズを bytes にする。dd が 1 ブロック bytes バイトで書き出しを行うようになる。デフォルトは 512 バイトである。

bs=bytes

入力、出力、両方のブロックサイズを bytes にする。dd が 1 ブロック bytes バイトで読み書きを行うようになり、‘ibs’ や ‘obs’ の指定は、あっても無効になる。なお、データ変換を行う ‘conv’ オプションが指定されていない場合は、入力は、それがブロックサイズより小さくても、 読み込まれるやいなや、出力にコピーされることになる。

cbs=bytes

変換ブロックサイズを bytes にする。 可変長のレコードを固定長のレコードに変換するときや (‘conv=block’)、その逆を行うとき (‘conv=unblock’)、固定長レコードの長さとして bytes の値を使用する。

skip=n

入力ファイルで ‘ibs’ バイトのブロックを n 個読み飛ばしてから、 コピーを行う。‘iflag=skip_bytes’ が指定されている場合は、n はブロック数ではなく、バイト数と見なされる。

seek=n

出力ファイルで ‘obs’ バイトのブロックを n 個スキップしてから、 コピーを行う。‘oflag=seek_bytes’ が指定されている場合は、 n はブロック数ではなく、バイト数と見なされる。

count=n

入力ファイルの末尾まで全部ではなく、‘ibs’ バイトのブロックを n 個だけ入力ファイルからコピーする。‘iflag=count_bytes’ が指定されている場合は、n はブロック数ではなく、バイト数と見なされる。 なお、次のことに注意してほしい。パイプから読み込んでいる場合などに時おり起きることだが、 入力からの読み込みがブロックの大きさに足りないことがある。そうした場合に ‘iflag=fullblock’ が指定してあると、‘count=’ は、一杯になるまで読み込むブロックの個数を意味するようになる。 入力から読み込みを実行する回数という POSIX で規定されている伝統的な動作ではなくなるのだ。

status=level

通常では ‘INFO’ シグナルを受け取った時点や、dd が終了したときに、 転送情報が標準エラーに出力される。 level の指定によって、表示する情報の量を調節することができる。 指定された level のうち、最後のものが優先される。

none

情報メッセージや警告メッセージを標準エラーに全く表示しない。 エラーメッセージは通常どおり出力する。

noxfer

最終的な転送速度や転送量の統計を表示しない。通常は、そうした情報がステータス表示の最後の行になる。

progress

各入力ブロックを処理するとき、転送速度と転送量の統計を標準エラーに表示する。 転送量の統計は 1 行に表示され、最も頻繁な場合、1 秒ごとに出力されるが、 I/O 待ちが起きると、更新が遅れることがある。

conv=conversion[,conversion]…

conversion 引数 (複数可) で指定されたようにファイルを変換する。 (コンマの前後にスペースを入れてはいけない。)

conversion には次のものが指定できる:

ascii

POSIX が規定している変換テーブルを使って、EBCDIC を ASCII に変換する。 変換テーブル中の 256 バイトのすべてについて、1 対 1 の変換が行われる。 このオプションを指定すると、‘conv=unblock’ も指定されることになる。 入力はまず ASCII に変換され、その後で末尾のスペースが除去される。

ebcdic

ASCII を EBCDIC に変換する。これは ‘ascii’ 変換の逆の動作である。 このオプションを指定すると、‘conv=block’ も指定されることになる。 末尾にスペースが追加されてから、EBCDIC に変換される。

ibm

この指定の動作は ‘conv=ebcdic’ に似ている。 ただし、POSIX が規定しているもう一つの変換テーブルを使って、変換する点が違う。 こちらは 1 対 1 の変換ではないが、‘~’, ‘[’, ‘]’ について、よく使われる伝統的な慣行を反映している。

ascii’, ‘ebcdic’, ‘ibm’ は、どれか一つしか指定できない。 こうしたオプションの一つを使う場合は、‘cbs=’ も指定すべきである。

block

入力 1 行あたり、‘cbs’ バイトを出力する。 入力中の改行はスペースに置き換え、‘cbs’ バイトに足りない分はスペースで埋める。

unblock

cbs’ バイトの大きさからなる各入力ブロックに対して、末尾にスペースがあれば、 それをすべて削除し、改行を追加する。

block’ と ‘unblock’ は、どちらか一方しか指定できない。

lcase

大文字を小文字に変換する。

ucase

小文字を大文字に変換する。

lcase’ と ‘ucase’ は、どちらか一方しか指定できない。

sparse

出力ブロックが NUL のみからなっているとき、それを書き出さずに、seek を試みる。 穴空きファイル (sparse file) をサポートしているシステムでは、 この動作は、出力ファイルを書き出しているときに、穴空きの出力を作成することになる。 このオプションを ‘conv=notrunc’ や ‘oflag=append’ と一緒に使う際は、気をつけなければならない。‘conv=notrunc’ が付いていると、 入力中の NUL ブロックに対応する位置にある、出力ファイル中の存在するデータは、 そのまま保持されることになる。‘oflag=append’ を付けた場合は、 seek は行っても効果がない。なお、‘conv=sparse’ では、 出力先がファイルではなく、デバイスの場合も、入力中の NUL ブロックはやはりコピーされない。 そんなわけで、このオプションが最も役に立つのは、仮想デバイスや、前もって 0 で初期化したデバイスに対してである。

swab

入力された全バイトを 2 個づつ組にして、前後を入れ替える。GNU の dd は、他の dd とは違って、読み込むバイトが奇数個でも動作する。 最後のバイトは (入れ替えるものがないので) そのままコピーするのである。

sync

すべての入力ブロックに対して ‘ibs’ の大きさになるまで、末尾をゼロバイトで埋める。 ‘block’ や ‘unblock’ と一緒に使用すると、ゼロバイトの代わりにスペースで埋める。

以下の conversion は、実のところファイルの扱いに関するフラグなので、内的な処理には影響を及ぼさない。

excl

出力ファイルがすでに存在する場合は、実行に失敗する。 言い換えれば、dd が出力ファイルを自分で作成しなければならないということである。

nocreat

出力ファイルを作成しない。言い換えれば、出力ファイルは前もって存在していなければならないということだ。

excl’ と ‘nocreat’ は、どちらか一方しか指定できない。

notrunc

出力ファイルに対して短縮操作をしない (訳注: ‘of=file’ の項を参照)。

noerror

読み込みエラーがあっても、作業を続行する。

fdatasync

コマンドを終了する直前に、出力データを同期させる。 すなわち、出力データをディスクに実際に書き込む。

fsync

コマンドを終了する直前に、出力データだけでなく、メタデータも同期させる。 すなわち、出力データとメタデータをディスクに実際に書き込む。

iflag=flag[,flag]…

引数 flag によって指定されたフラグを使って、入力ファイルにアクセスする。 (コンマの前後にスペースを入れてはいけない。)

oflag=flag[,flag]…

引数 flag によって指定されたフラグを使って、出力ファイルにアクセスする。 (コンマの前後にスペースを入れてはいけない。)

フラグには次のものがある。どのオペレーティング・システムでも、 すべてのフラグが使えるわけではない。

append

追加モードで書き込む。従って、何か別のプロセスが問題のファイルに書き出している場合でも、 dd の書き込みは、書き込むたびに、そのファイルの今現在の内容に追加されることになる。 このフラグは出力に対してしか意味がない。なお、このフラグを ‘of=file’ オペランドと組み合わせて使うのなら、 ‘conv=notrunc’ も一緒に指定した方がよい。 さもないと、出力ファイルは、追加書き込みが始まる前に、短縮操作を受けることになる。

cio

データに対してコンカレント I/O (CIO) モードを使用する。 このモードでは、ダイレクト I/O を行いつつ、同じファイルに対するすべての I/O は順番に行わなければならないという POSIX の要件は無視する。 一つのファイルを CIO モードと標準的な方法の両方で同時にオープンすることはできない。

direct

データに対してダイレクト I/O を使用し、バッファ・キャッシュを介さないようにする。 カーネルが read バッファや write バッファのサイズに制限をかけていることがあるのに注意していただきたい。 たとえば、出力先のファイルシステムが ext4 で、カーネルが linux ベースの場合、出力バッファのサイズが 512 の倍数でなければ、‘oflag=direct’ を指定すると、EINVAL で書き込みに失敗することになる。

directory

ファイルがディレクトリでなければ、実行に失敗する。 ほとんどのオペレーティング・システムがディレクトリに対する I/O を許していない。従って、このフラグが役に立つ機会はめったにない。

dsync

データに対して同期 I/O を使用する。出力ファイルについては、 このフラグは、各書き込みごとに出力データをディスクに実際に書き込ませる。 入力ファイルについてこのフラグが意味を持つかもしれないのは、 読み込んでいるのがリモートのファイルであり、 それが何か他のプロセスによって同期的に書き込まれているときである。 メタデータ (たとえば、最終アクセス日時や最終更新日時) は、必ずしも同期されない。

sync

データとメタデータに対して同期された I/O を使用する。

nocache

システムの持つファイルのデータ・キャッシュを廃棄するよう要求する。 count=0 の場合は、ファイルのキャッシュされたデータ全体を指定することになる。 それ以外の場合は、ファイルのキャッシュのうち、処理の対象になった部分だけが捨てられる。 また、count=0 のとき、キャッシュの廃棄に失敗すると、 その旨メッセージが表示され、終了ステータスに反映する。

念のために言っておくと、 ストレージへの書き込みがまだ終了していないデータが、キャッシュから捨てられることはない。 そこで、下記の用例で “sync” オプションを使っていることに注目していただきたい。 ‘nocache’ フラグの効率を最大にするために使用しているのである。

用例をいくつか挙げておく。

 
# ファイル全体のキャッシュを捨てるように指示する。
dd if=ifile iflag=nocache count=0

# ファイル全体のキャッシュを確実に捨てる。
dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0

# ファイル中の一部分のキャッシュを捨てる。
dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null

# read-ahead キャッシュのみを使って、データを転送する。
# ‘direct’ フラグの項も参照すること。
dd if=ifile of=ofile iflag=nocache oflag=nocache,sync
nonblock

ノンブロッキング I/O を使用する。

noatime

ファイルのアクセス日時を更新しない。古いシステムの中には、 エラーや警告も出さずに、このフラグを無視するものがある。 そこで、このフラグを使用する前に、有効かどうか、お手元のファイルで試してみるとよい。

noctty

入力 (または、出力) ファイルを dd の制御端末にしない。 このフラグは、そのファイルが端末でなければ、効果がない。 このフラグが全く効果を持たないホストが、たくさんある (たとえば、GNU/Linux ホストがそうである)。

nofollow

シンボリックリンクをたどらない。

nolinks

ファイルに複数のハードリンクがあれば、実行に失敗する。

binary

バイナリ I/O を使用する。このフラグは、バイナリ I/O とテキスト I/O を区別する非標準的なプラットフォームでしか効果がない。

text

テキスト I/O を使用する。このフラグが標準的なプラットフォームで効果がないのは、 ‘binary’ と同様である。

fullblock

各ブロックが一杯になるまで入力から読み込む。read システムコールは、 入力がブロックの分量に足りない場合、早めに戻ってくることがある。 そうした場合に、read の呼び出しを繰り返して、ブロックの残りを埋めようとする。 このフラグは、iflag でのみ使用できる。 このフラグが役に立つのは、たとえばパイプと組み合わせて使うときである。 パイプとの組み合わせでは、入力からの読み込みがブロックの大きさに足りないことがあるからだ。 そうした場合に、‘count=’ の引数が、読み込み動作の回数ではなく、 読み込むブロック数だと確実に解釈されるようにするには、このフラグが必要になる。

count_bytes

count=’ オペランドをブロック数ではなく、バイト数の指定と見なす。 そうすることで、I/O ブロックサイズの倍数ではない長さが、指定できるようになるわけだ。 このフラグは iflag でしか使用できない。

skip_bytes

skip=’ オペランドをブロック数ではなく、バイト数の指定と見なす。 そうすることで、I/O ブロックサイズの倍数ではないオフセットが、指定できるようになるわけだ。 このフラグは iflag でしか使用できない。

seek_bytes

seek=’ オペランドをブロック数ではなく、バイト数の指定と見なす。 そうすることで、I/O ブロックサイズの倍数ではないオフセットが、指定できるようになるわけだ。 このフラグは oflag でしか使用できない。

以上のフラグは、すべてのシステムでサポートされているわけではなく、 サポートされていないシステムで使用しようとすると、‘dd’ に拒否される。 標準入力から読み込んでいる場合や、標準出力に書き出している場合は、 ‘nofollow’ や ‘noctty’ フラグは指定するべきではない。 また、他のフラグ (たとえば ‘nonblock’) は、 対象となるファイルのファイル・ディスクリプタに対する他のプロセスの動作に、dd が終了した後までも、影響を及ぼすかもしれない。

上記中の数値を表す文字列 (nbytes) には、乗数を示す文字を後ろに付けることができる。 すなわち、‘b’=512, ‘c’=1, ‘w’=2, ‘xm’=m といった文字である (訳注: 最後のものは、10xM という表記は 10M と書くのと同じだということ)。 あるいは、‘k’=1024 のような、ブロックサイズに付ける標準の接尾辞の一つを続けてもよい (see section ブロックサイズ)。

bs=’, ‘ibs=’, ‘obs=’, "‘cbs=’ を使って指定するブロックサイズは、 大きすぎない方がよい。数メガバイトを越える値は、一般的に言って無駄だし、 (ギガバイト … エクサバイトを使ったときのように) 全く逆効果だったり、 エラーの元になったりする。

データのオフセット位置やサイズが I/O ブロックサイズの倍数ではない場合に、 そうしたデータを処理するには、‘skip_bytes’, ‘seek_bytes’, ‘count_bytes’ といったフラグを使用すればよい。あるいは、dd を別々に呼び出すという伝統的な手法を使用することもできる。 一例を挙げると、以下のシェルコマンドは、1 ブロック を 512 KiB にして、ディスクとテープの間でデータをコピーしている。 ただし、ディスクの先頭にある 4 KiB のラベルについては、保存も復元も行っていない。

 
disk=/dev/rdsk/c0t1d0s2
tape=/dev/rmt/0

# ラベル以外のすべてをディスクからテープへコピーする。
(dd bs=4k skip=1 count=0 && dd bs=512k) <$disk >$tape

# テープからディスクへ書き戻す。ただし、ディスクのラベルには手を
# 付けない。
(dd bs=4k seek=1 count=0 && dd bs=512k) <$tape >$disk

壊れかけたディスクについては、様々なおまけ機能が付いたツールが他にあり、 そうしたものを使えば、ディスクが本当にダメになってしまう前に、できるだけ多くのデータを救済することが容易になる。 たとえば、GNU ddrescue がその一つだ。 しかしながら、場合によっては、そうしたツールが使えないこともあるし、 管理者にとって dd を操作する方が安心できるということもある。 そうした場合は、簡単なレスキュー方法として、dd を以下の例で示すように実行すればよい。 ‘conv=noerror,sync’ オプションを使っているのは、リードエラーがあっても続行し、 読み込めなかった部分 (bad read) を NUL で埋めるためである。 また、‘iflag=fullblock’ は、ショートリードに対する用心だ (そうしたことが磁気ディスクを使っているデバイスで起きたことは、これまでにないけれど)。

 
# 壊れかけたディスクのパーティションから (マウントしていない
# パーティションだ!) データを救済する。
dd conv=noerror,sync iflag=fullblock </dev/sda1 > /mnt/rescue.img

実行中の dd のプロセスに ‘INFO’ シグナルを送ると (それが使えないシステムでは、‘USR1’ シグナルを送る)、 dd は入出力の統計情報を標準エラーに書き出し、それからコピー作業を続行する。 以下の例では、dd をバックグラウンドで実行し 5GB のデータのコピーを行っている。kill コマンドが実行されると、 dd は実行途中の入出力統計を表示する。 そして、正常に作業を完了するか、SIGINT シグナルによって中断されたとき、 最終的な統計情報を出力する。

 
# シェルが子プロセスである dd をうっかり終了させてしまうことが
# 絶対にないように、USR1 シグナルを「無視する」にしておく。
# なお、SIGINFO が利用できる場合は、これをやる必要はない。
trap '' USR1

# シグナルを受けることが引き鉄になって、ショートリードが起きるかも
# しれない。それを避けるために、dd を iflag=fullblock で実行する。
dd iflag=fullblock if=/dev/zero of=/dev/null count=5000000 bs=1000 & pid=$!

# 1 秒ごとに統計情報を出力する。
while kill -s USR1 $pid 2>/dev/null; do sleep 1; done

上記のスクリプトの出力は、次のようなフォーマットになる。

 
3441325+0 records in
3441325+0 records out
3441325000 bytes (3.4 GB, 3.2 GiB) copied, 1.00036 s, 3.4 GB/s
5000000+0 records in
5000000+0 records out
5000000000 bytes (5.0 GB, 4.7 GiB) copied, 1.44433 s, 3.5 GB/s

status=progress’ オプションを付けると、転送統計を表す上記の最後の行が定期的に更新される。

INFO’ シグナルが存在しないシステムでは、 環境変数 POSIXLY_CORRECT が設定されていないかぎり、dd は ‘INFO’ の代わりに ‘USR1’ に反応する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated on June 7, 2022 using texi2html 1.82.