web-dev-qa-db-ja.com

コマンドddの 'seek'引数

次の行で何が起こっているのかを説明できる人はいますか?

dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes

特にシーク部分がはっきりしない

マンページは言う:

 seek=BLOCKS
              skip BLOCKS obs-sized blocks at start of output

Obsサイズのブロックとは何ですか?

21
user2799508

ddはコピーするように設計されています ブロック 入力ファイルから出力ファイルへのデータの変換。 ddブロックサイズオプションは man page から次のとおりです。

_ibs=expr
    Specify the input block size, in bytes, by expr (default is 512).
obs=expr
    Specify the output block size, in bytes, by expr (default is 512).
bs=expr
    Set both input and output block sizes to expr bytes, superseding ibs= and obs=.
_

ddseekオプションは、UNIX lseek()システムコールに似ています。1。ファイル内で読み取り/書き込みポインタを移動します。 man page から:

_seek=n
    Skip n blocks (using the specified output block size) from the beginning of the output file before copying. 
_

UNIXの通常のファイルには、最初から読み書きする必要がないという便利な特性があります。どこからでもシークして、そこから読み書きできます。したがって、_bs=4096 seek=7_は、出力ファイルの先頭から7 * 4096バイトの位置に移動し、そこから書き込みを開始することを意味します。ファイルの0〜7 * 4096バイトの部分には書き込みません。

まったく書き込まれない通常のファイルの領域は、基盤となるファイルシステムによっても割り当てられません。これらのエリアは  そしてファイルが呼び出されます スパースファイル。あなたの例では、_file_with_holes_は最初に7 * 4096バイトの穴があります。 (h/t @frostschutzは、デフォルトでddが出力ファイルを切り捨てることを指摘しています。)

これらの未割り当て領域を読み取ることは問題ありません。あなたはゼロの束を取得します。

[1] ddが作成されたとき、類似のシステムコールはseek()でした。

23
Mark Plotnick

他の回答ですでに説明されていますが、疑問がある場合は、ddstraceで何をするかを確認できます。

$ strace dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes
# output is shortened considerably
open("/dev/urandom", O_RDONLY)          = 0
open("file_with_holes", O_RDWR|O_CREAT, 0666) = 1
ftruncate(1, 28672)                     = 0
lseek(1, 28672, SEEK_CUR)               = 28672
read(0, "\244\212\222v\25\342\346\226\237\211\23\252\303\360\201\346@\351\6c.HF$Umt\362;E\233\261"..., 4096) = 4096
write(1, "\244\212\222v\25\342\346\226\237\211\23\252\303\360\201\346@\351\6c.HF$Umt\362;E\233\261"..., 4096) = 4096
read(0, "~\212q\224\256\241\277\344V\204\204h\312\25pw9\34\270WM\267\274~\236\313|{\v\6i\22"..., 4096) = 4096
write(1, "~\212q\224\256\241\277\344V\204\204h\312\25pw9\34\270WM\267\274~\236\313|{\v\6i\22"..., 4096) = 4096
close(0)                                = 0
close(1)                                = 0
write(2, "2+0 records in\n2+0 records out\n", 312+0 records in
2+0 records out
) = 31
write(2, "8192 bytes (8.2 kB) copied", 268192 bytes (8.2 kB) copied) = 26
write(2, ", 0.00104527 s, 7.8 MB/s\n", 25, 0.00104527 s, 7.8 MB/s
) = 25
+++ exited with 0 +++

読み取り用に/dev/urandomを開き(if=/dev/urandom)、作成/書き込み用にfile_with_holesを開きます(of=file_with_holes)。

次に、file_with_holes4096*7 = 28672バイト(bs=4096 seek=7)に切り捨てます。切り捨てとは、その位置以降のファイルの内容が失われることを意味します。 (この手順を回避するには、conv=notruncを追加します)。次に、28672バイトをシークします。

次に、4096からbs=4096バイト(/dev/urandomibsとして使用)を読み取り、4096バイト(bs=4096obs)からfile_with_holesへ、次に別の読み取りと書き込み(count=2)へ。

次に、/dev/urandomを閉じ、file_with_holesを閉じ、2*4096 = 8192バイトをコピーしたことを出力します。最後にエラーなしで終了します(0)。

6
frostschutz

obsは出力ブロックサイズ、ibsは入力ブロックサイズです。 bsまたはibsなしでobsを指定すると、両方に使用されます。

したがって、シークは、出力の開始時に4096または28672バイトの7ブロックになります。次に、入力の開始から出力のこのポイントまで、4096または8192バイトの2つのブロックをコピーします。

5
Graeme

Seekは出力ファイルを「膨らませる」だけです。 Seek = 7は、出力ファイルの先頭に、出力ブロックサイズ= obs = 4096バイトの7つの「空の」ブロックが挿入されることを意味します。これは非常に大きなファイルをすばやく作成する方法です。

1
Thorsten Staerk