Argumen 'seek' dalam perintah dd

20

Bisakah beberapa orang menjelaskan kepada saya apa yang terjadi pada baris berikut?

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

terutama mencari bagian tidak jelas

Halaman manual mengatakan:

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

Apa itu blok ukuran obs?

pengguna2799508
sumber

Jawaban:

22

dddirancang untuk menyalin blok data dari file input ke file output. The ddpilihan ukuran blok adalah sebagai berikut, dari halaman manual :

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

The dd seekpilihan adalah mirip dengan UNIX lseek()system call 1 . Ini memindahkan pointer baca / tulis dalam file. Dari halaman manual :

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

File biasa di UNIX memiliki properti nyaman yang Anda tidak perlu membaca atau menulisnya mulai dari awal; Anda dapat mencari di mana saja dan membaca atau menulis mulai dari sana. Jadi bs=4096 seek=7artinya pindah ke posisi 7 * 4096 byte dari awal file output dan mulai menulis dari sana. Itu tidak akan menulis ke bagian file yang antara 0 dan 7 * 4096 byte.

Area file biasa yang tidak pernah ditulis sama sekali bahkan tidak dialokasikan oleh sistem file yang mendasarinya. Daerah-daerah ini disebut lubang dan file-file ini disebut file jarang . Dalam contoh Anda, file_with_holesakan memiliki lubang 7 * 4096-byte di awal. (h / t @frostschutz untuk menunjukkan bahwa ddmemotong file output secara default.)

Tidak masalah untuk membaca area yang tidak terisi ini; Anda mendapatkan banyak nol.

[1] kembali ketika ddditulis, panggilan sistem analog adalah seek().

Tandai Plotnick
sumber
Menarik, halaman buku panduan saya sangat mengganggu tentang hal ini - `bs = BYTES membaca dan menulis hingga byte BYTES sekaligus`
Graeme
Saya belum melihat "mencari" di UNIX, Mungkin "lseek" kurasa.
kangear
1
Sebagai catatan, saya mencoba mencari perangkat penggerak ( dd if=/dev/zero bs=512 count=2 seek=8388607998 of=/dev/sddexmaple 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
:)
1
@Akses perangkat Disk biasanya dicari, tetapi mungkin ada beberapa masalah dengan perangkat yang sangat besar. Seberapa besar (dalam byte) / dev / sdd Anda?
Mark Plotnick
1
Mungkin saya pernah sebelumnya dan tidak ingat. Saya mencoba mengakses sektor GPT cadangan atau 2 di akhir disk 4TB.
Pysis
6

Jawaban lain sudah menjelaskannya, tetapi jika Anda memiliki keraguan, Anda dapat melihat apa hubungannya dddengan itu 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 +++

Ini terbuka /dev/urandomuntuk membaca ( if=/dev/urandom), terbuka file_with_holesuntuk buat / tulis ( of=file_with_holes).

Kemudian memotong file_with_holeske 4096*7= 28672byte ( bs=4096 seek=7). Truncate berarti bahwa isi file setelah posisi itu hilang. (Tambahkan conv=notruncuntuk menghindari langkah ini). Kemudian ia berusaha untuk 28672byte.

Kemudian ia membaca 4096byte ( bs=4096digunakan sebagai ibs) dari /dev/urandom, menulis 4096byte ( bs=4096digunakan sebagai obs) file_with_holes, diikuti oleh baca dan tulis ( count=2) lainnya.

Kemudian menutup /dev/urandom, menutup file_with_holes, dan mencetak yang disalin 2*4096= 8192byte. Akhirnya keluar tanpa kesalahan (0).

frostschutz
sumber
5

obsadalah ukuran blok output dan ibsmerupakan ukuran blok input. Jika Anda menentukan bstanpa ibsatau obsini digunakan untuk keduanya.

Jadi pencarian Anda akan menjadi 7 blok 4096 atau 28672 byte pada awal output Anda. Kemudian Anda akan menyalin 2 blok dari 4096 atau 8192 byte dari awal input ke titik ini di output.

Graeme
sumber
1

Carilah hanya "mengembang" file output. Seek = 7 berarti pada awal file output, 7 blok "kosong" dengan ukuran blok output = obs = 4096bytes akan dimasukkan. Ini adalah cara untuk membuat file yang sangat besar dengan cepat.

Thorsten Staerk
sumber
1
Atau untuk melewatkan data di awal yang tidak ingin Anda ubah. Blok kosong hanya dihasilkan jika file output pada awalnya tidak memiliki banyak data. Manual juga tidak jelas tentang bagaimana obshubungannya dengan bs, perintah menggunakan bsyang akan menggantikan obsjika tidak ada.
Graeme