コマンドddの 'seek'引数


20

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

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サイズのブロックとは何ですか?

回答:


22

dd入力ファイルから出力ファイルにデータのブロックをコピーするように設計されています。ddブロックサイズオプションから、次のようにしているmanページ

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=.

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

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バイトの穴があります。(ddデフォルトで出力ファイルを切り捨てることを指摘したh / t @frostschutz 。)

これらの未割り当て領域を読み取ってもかまいません。たくさんのゼロを取得します。

[1] dd書かれたとき、類似のシステムコールはでしたseek()


`BS = BYTES読み、time`でBYTESバイトまで書き込み-面白い、私のmanページにはうるさく、この上unforthcomingされる
グレアム・

UNIXで「seek」を見たことがありません。おそらく「lseek」だと思います。
kangear 14年

1
ただ注意してください、私はドライブデバイス(例:)を探していましたdd if=/dev/zero bs=512 count=2 seek=8388607998 of=/dev/sddが、それらの「ファイル」/記述子は検索できません:dd: /dev/sdd: cannot seek: Invalid argument 0+0 records in 0+0 records out 0 bytes copied, 0.00765396 s, 0.0 kB/s
Pysis

1
@Pysis Diskデバイスは通常シーク可能ですが、非常に大きなデバイスにはいくつかの問題があるかもしれません。/ dev / sddの大きさ(バイト単位)は?
マークプロトニック

1
たぶん前に持っていて覚えていないかもしれません。バックアップGPTセクターまたは4TBディスクの最後にある2にアクセスしようとしています。
ピシス

6

他の回答には、すでにそれを説明したが、あなたは疑問を持っている場合、あなたは何を見ることができddていstrace

$ 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として使用ibsから)/dev/urandom書き込む4096(バイトbs=4096として使用obsする)file_with_holes別の読み取りおよび書き込み(続いてcount=2)。

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


5

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

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


1

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


1
または、変更したくないデータを最初からスキップする。空のブロックは、出力ファイルに最初はそれほど多くのデータがなかった場合にのみ発生します。マニュアルには、どのように明確ではありませんobsに関しbs、コマンドが使用するbsどの代用しますobsそれがない場合。
グレアム14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.