短いバージョン:データのコピーにdd
安全に使用できるのはどのような場合ですか?部分的な読み取りまたは書き込み?
Long version — preamble:dd
は、特にデバイスとの間でデータをコピーするためによく使用されます( 例 =)。これは、他のツールよりも低いレベルでデバイスにアクセスできるという神秘的なプロパティに起因する場合があります(実際には、魔法をかけているのはデバイスファイルです)—しかし、dd if=/dev/sda
はcat /dev/sda
と同じです。 dd
の方が速いと思われることもありますが、実際には cat
の方が優れています 。それにもかかわらず、 dd
には固有のプロパティがあり、時々本当の意味で役立つ 。
問題:dd if=foo of=bar
は実際にはcat <foo >bar
と同じではありません。ほとんどのユニスでは、dd
は read()
を1回呼び出します。 (dd
の「入力ブロックの読み取り」を構成するものについて [〜#〜] posix [〜#〜] ファジーを見つけます。)read()
が部分的な結果(POSIXおよびその他の参照ドキュメントによれば、実装のドキュメントに別の指示がない限り許可されます)、部分的なブロックがコピーされます。まったく同じ問題がwrite()
にも存在します。
観察:実際には、dd
がブロックデバイスと通常のファイルに対応できることがわかりましたが、それはあまり運動していません。パイプに関しては、dd
に問題があることは難しくありません。たとえば、試してみてください このコード :
yes | dd of=out bs=1024k count=10
out
ファイルのサイズを確認します(おそらく10MB未満です)。
質問:データのコピーにdd
を使用しても安全なのはどのような場合ですか?言い換えると、dd
がすべてのデータを確実にコピーできるようにするには、ブロックサイズ、実装、ファイルタイプなどのどの条件を使用できますか?
( GNU dd には、ループ内でread()
またはwrite()
を呼び出してブロック全体を転送するように指示するfullblock
フラグがあります。したがって、dd iflag=fullblock
は常に安全です。私の質問は、これらのフラグ(他の実装には存在しない)が使用されない場合についてです。
¹ OpenBSD、GNU coreutilsおよびBusyBoxで確認しました。
ソケット、パイプ、またはttyを使用すると、read()およびwrite()は要求されたサイズ未満で転送できるため、これらでddを使用する場合は、fullblockフラグが必要です。ただし、通常のファイルとブロックデバイスでは、短い読み取り/書き込みを実行できるのは、EOFに達したとき、またはエラーが発生したときの2回だけです。これが、fullblockフラグのない古いddの実装がディスク複製に安全に使用できる理由です。