Ringkasan: dd
adalah alat rewel yang sulit digunakan dengan benar. Jangan gunakan itu, meskipun banyak tutorial yang memberitahu Anda begitu. dd
memiliki getaran "unix street cred" yang melekat padanya - tetapi jika Anda benar-benar memahami apa yang Anda lakukan, Anda akan tahu bahwa Anda tidak boleh menyentuhnya dengan tiang 10 kaki.
dd
melakukan satu panggilan ke panggilan read
sistem per blok (ditentukan oleh nilai bs
). Tidak ada jaminan bahwa read
panggilan sistem mengembalikan data sebanyak ukuran buffer yang ditentukan. Ini cenderung berfungsi untuk file biasa dan memblokir perangkat, tetapi tidak untuk pipa dan beberapa perangkat karakter. Lihat Kapan dd cocok untuk menyalin data? (atau, ketika dibaca () dan tulis () parsial) untuk informasi lebih lanjut. Jika read
panggilan sistem mengembalikan kurang dari satu blok penuh, maka dd
transfer sebagian blok. Masih menyalin jumlah blok yang ditentukan, sehingga jumlah total byte yang ditransfer kurang dari yang diminta.
Peringatan tentang "pembacaan parsial" memberi tahu Anda hal ini dengan tepat: salah satu bacaannya parsial, jadi dd
mentransfer blok yang tidak lengkap. Dalam jumlah blok, +1
berarti satu blok dibaca sebagian; karena jumlah outputnya adalah +0
, semua blok ditulis sebagai telah dibaca.
Ini tidak mempengaruhi keacakan data: semua byte yang dd
menulis adalah byte yang dibaca /dev/urandom
. Tetapi Anda mendapat byte lebih sedikit dari yang diharapkan.
Linux /dev/urandom
mengakomodasi permintaan besar yang sewenang-wenang (sumber: extract_entropy_user
dalam drivers/char/random.c
), jadi dd
biasanya aman saat membacanya. Namun, membaca data dalam jumlah besar membutuhkan waktu. Jika proses menerima sinyal, read
panggilan sistem kembali sebelum mengisi buffer outputnya. Ini adalah perilaku normal, dan aplikasi seharusnya memanggil read
dalam satu lingkaran; dd
tidak melakukan ini, karena alasan historis ( dd
asal-usulnya suram, tetapi tampaknya telah dimulai sebagai alat untuk mengakses kaset, yang memiliki persyaratan khusus, dan tidak pernah diadaptasi menjadi alat tujuan umum). Saat Anda memeriksa progresnya, ini mengirimkan dd
proses sinyal yang mengganggu pembacaan. Anda memiliki pilihan antara mengetahui berapa bytedd
akan menyalin secara total (pastikan untuk tidak menghentikannya - tidak ada pemeriksaan kemajuan, tidak ada penangguhan), atau mengetahui berapa banyak byte yang dd
telah disalin sejauh ini, dalam hal ini Anda tidak bisa tahu berapa banyak lagi byte yang akan disalin.
Versi dd
dalam GNU coreutils (seperti yang ditemukan pada Linux yang tidak tertanam dan pada Cygwin) memiliki bendera fullblock
yang memberitahu dd
untuk memanggil read
dalam satu lingkaran (dan juga untuk write
) dan dengan demikian selalu mentransfer blok penuh. Pesan kesalahan menyarankan agar Anda menggunakannya; Anda harus selalu menggunakannya (dalam flag input dan output), kecuali dalam keadaan yang sangat khusus (kebanyakan ketika mengakses kaset) - jika Anda menggunakan dd
semuanya, yaitu: biasanya ada solusi yang lebih baik (lihat di bawah).
dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000
Cara lain yang mungkin untuk memastikan apa yang dd
akan dilakukan adalah dengan melewatkan ukuran blok 1. Kemudian Anda dapat mengetahui berapa banyak byte yang disalin dari jumlah blok, meskipun saya tidak yakin apa yang akan terjadi jika a read
terganggu sebelum membaca yang pertama. byte (yang sangat tidak mungkin dalam praktek tetapi bisa terjadi). Namun, bahkan jika itu berhasil, ini sangat lambat.
Saran umum tentang penggunaan dd
adalah jangan gunakandd
. Meskipun dd
sering diiklankan sebagai perintah tingkat rendah untuk mengakses perangkat, sebenarnya tidak ada hal seperti itu: semua keajaiban terjadi pada file perangkat (bagian /dev/…
), dd
hanyalah alat biasa dengan potensi penyalahgunaan yang tinggi yang mengakibatkan hilangnya data . Dalam kebanyakan kasus, ada cara yang lebih sederhana dan lebih aman untuk melakukan apa yang Anda inginkan, setidaknya di Linux.
Misalnya, untuk membaca sejumlah byte pada awal file, panggil saja head
:
head -c 1000000m </dev/urandom >file
Saya membuat patokan cepat pada mesin saya dan tidak melihat perbedaan kinerja antara dd
dengan ukuran blok yang besar dan head
.
Jika Anda perlu melewati beberapa byte di awal, pipa tail
ke head
:
dd if=input of=output count=C bs=B seek=S
<input tail -c +$((S*B+1)) | head -c $((C*B)) >output
Jika Anda ingin melihat kemajuan, panggil lsof
untuk melihat offset file. Ini hanya berfungsi pada file biasa (file output pada contoh Anda), bukan pada perangkat karakter.
lsof -a -p 1234 -d 1
cat /proc/1234/fdinfo/1
Anda dapat menelepon pv
untuk mendapatkan laporan kemajuan (lebih baik dari dd
pada), dengan mengorbankan item tambahan di dalam pipa (dari sisi kinerja, hampir tidak terlihat).