Saya membuat file 1TB dengan data acak dd if=/dev/urandom of=file bs=1M count=1000000
. Sekarang saya memeriksa kill -SIGUSR1 <PID>
perkembangannya dan mendapatkan yang berikut:
691581+0 Datensätze ein
691580+0 Datensätze aus
725174190080 Bytes (725 GB) kopiert, 86256,9 s, 8,4 MB/s
800950+1 Datensätze ein
800950+0 Datensätze aus
839856947200 Bytes (840 GB) kopiert, 99429,5 s, 8,4 MB/s
dd: warning: partial read (809620 bytes); suggest iflag=fullblock
803432+1 Datensätze ein
803431+1 Datensätze aus
842459273876 Bytes (842 GB) kopiert, 99791,3 s, 8,4 MB/s
Saya tidak bisa menafsirkan peringatan itu. Apa yang dikatakan? Apakah file saya benar-benar acak setelah peringatan atau ada masalah? Apa artinya +0 atau +1 800950+1 Datensätze ein
dan 800950+0 Datensätze aus
artinya? Setelah peringatan itu +1. Apakah ini jumlah kesalahan?
LC_ALL=C
di depan perintah, sepertiLC_ALL=C dd if=...
Jawaban:
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 panggilanread
sistem per blok (ditentukan oleh nilaibs
). Tidak ada jaminan bahwaread
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. Jikaread
panggilan sistem mengembalikan kurang dari satu blok penuh, makadd
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
dalamdrivers/char/random.c
), jadidd
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 memanggilread
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 mengirimkandd
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 yangdd
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 benderafullblock
yang memberitahudd
untuk memanggilread
dalam satu lingkaran (dan juga untukwrite
) 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 menggunakandd
semuanya, yaitu: biasanya ada solusi yang lebih baik (lihat di bawah).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 aread
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
. Meskipundd
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
:Saya membuat patokan cepat pada mesin saya dan tidak melihat perbedaan kinerja antara
dd
dengan ukuran blok yang besar danhead
.Jika Anda perlu melewati beberapa byte di awal, pipa
tail
kehead
: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.Anda dapat menelepon
pv
untuk mendapatkan laporan kemajuan (lebih baik daridd
pada), dengan mengorbankan item tambahan di dalam pipa (dari sisi kinerja, hampir tidak terlihat).sumber
dd
perintah yang tidak saya sadari perlu saya ketahui. Terima kasih.dd
dapat digunakan dengan aman, berkatfullblock
pilihannya. Tetapi jika Anda memiliki GNU coreutils, Anda tidak perludd
banyak. “Derivatif” sepertidcfldd
yang tidakdd
, mereka tidak menderita cacat desain, jadi jawaban saya tidak berlaku untuk mereka. Mayoritas orang yang menggunakandd
belum meluangkan waktu untuk memahaminya (paling banyak, mereka meluangkan waktu untuk berpikir bahwa mereka memahaminya) dan cara mereka menggunakannya menyebabkan hilangnya data.Peringatan terjadi ketika
dd
tidak bisa mendapatkan data yang cukup untuk mengisi blok dalam sekali baca. Ini terjadi dengan sumber data yang tidak menentu atau lambat, atau sumber yang menulis data dalam unit yang lebih kecil dari ukuran blok yang Anda minta.Tidak ada masalah dengan integritas data, tetapi masalahnya adalah bahwa
dd
sebagian membaca masih sebagai blok baca.Jika Anda tidak menggunakan
count
opsi, peringatan itu tidak terlalu berarti, itu hanya pertimbangan kinerja. Tetapi dengancount
, Anda tidak akan mendapatkan jumlah data yang Anda minta. Karena pembacaan parsial,of
akan lebih kecil daricount*bs
pada akhirnya.Jadi ketika Anda menggunakan
count
, secara teknis Anda harus selalu menggunakannyaiflag=fullblock
juga.The
+x
harus jumlah blok parsial.sumber
^ Itu hanya akan berhasil. Informasi yang keliru yang dinyatakan di sini secara nyata salah.
dd
Buffernya eksplisit dan untuk buffer input untuk menghitung kejadian Anda perlu buffer secara eksplisit. Itu semuanya. Jangan beli fud.sumber