สรุป: dd
เป็นเครื่องมือที่บ้าๆบอ ๆ ซึ่งยากต่อการใช้งานอย่างถูกต้อง อย่าใช้มันแม้จะมีบทเรียนมากมายที่บอกคุณ dd
มีกลิ่นอาย "ถนนยูนิกซ์" ติดอยู่กับมัน - แต่ถ้าคุณเข้าใจอย่างแท้จริงว่าคุณกำลังทำอะไรอยู่คุณจะรู้ว่าคุณไม่ควรแตะเสา 10 ฟุต
dd
ทำให้การเรียกครั้งเดียวไปยังการread
เรียกระบบต่อบล็อก (กำหนดโดยค่าของbs
) ไม่รับประกันว่าการread
เรียกของระบบจะส่งคืนข้อมูลมากเท่ากับขนาดบัฟเฟอร์ที่ระบุ สิ่งนี้มีแนวโน้มที่จะทำงานกับไฟล์และอุปกรณ์บล็อกปกติ แต่ไม่ใช่สำหรับไปป์และอุปกรณ์ตัวอักษรบางตัว ดูที่เมื่อใดจึงเหมาะสำหรับการคัดลอกข้อมูล (หรือเมื่อมีการอ่าน () และเขียน () บางส่วน)สำหรับข้อมูลเพิ่มเติม หากการread
เรียกระบบส่งคืนบล็อกเต็มน้อยกว่าหนึ่งบล็อกให้dd
โอนบล็อกบางส่วน มันยังคงคัดลอกจำนวนบล็อกที่ระบุดังนั้นจำนวนไบต์ที่ถ่ายโอนทั้งหมดจะน้อยกว่าที่ร้องขอ
คำเตือนเกี่ยวกับ“ การอ่านบางส่วน” จะบอกคุณตรงนี้: หนึ่งในการอ่านนั้นเป็นบางส่วนดังนั้นจึงdd
โอนบล็อกที่ไม่สมบูรณ์ ในการนับบล็อก+1
หมายถึงการอ่านบล็อกหนึ่งส่วน เนื่องจากจำนวนเอาต์พุตคือ+0
บล็อกทั้งหมดจึงถูกเขียนเป็นอ่าน
นี้ไม่ได้ส่งผลกระทบต่อการสุ่มของข้อมูล: ไบต์ทั้งหมดที่เขียนออกมาเป็นไบต์ว่ามันอ่านจากdd
/dev/urandom
แต่คุณมีไบต์น้อยกว่าที่คาดไว้
Linux /dev/urandom
รองรับการร้องขอขนาดใหญ่ตามอำเภอใจ (ที่มา: extract_entropy_user
ในdrivers/char/random.c
) ดังนั้นdd
โดยปกติแล้วจะปลอดภัยเมื่ออ่านจากมัน อย่างไรก็ตามการอ่านข้อมูลจำนวนมากต้องใช้เวลา หากกระบวนการได้รับสัญญาณการread
เรียกของระบบจะส่งกลับก่อนเติมบัฟเฟอร์เอาต์พุต นี่เป็นพฤติกรรมปกติและแอปพลิเคชันควรจะเรียกread
เป็นลูป dd
ไม่ได้ทำสิ่งนี้ด้วยเหตุผลทางประวัติศาสตร์ ( dd
ต้นกำเนิดมืดมัว แต่ดูเหมือนว่าจะเป็นเครื่องมือในการเข้าถึงเทปซึ่งมีข้อกำหนดแปลก ๆ และไม่เคยถูกดัดแปลงให้เป็นเครื่องมืออเนกประสงค์ทั่วไป) เมื่อคุณตรวจสอบความคืบหน้าสิ่งนี้จะส่งdd
สัญญาณที่ขัดจังหวะการอ่าน คุณมีทางเลือกระหว่างการรู้จำนวนไบต์dd
จะคัดลอกทั้งหมด (ตรวจสอบให้แน่ใจว่าจะไม่ขัดจังหวะ - ไม่มีการตรวจสอบความคืบหน้าไม่มีการหยุดชั่วคราว) หรือรู้ว่ามีกี่ไบต์ที่dd
คัดลอกมาแล้วซึ่งในกรณีนี้คุณไม่สามารถรู้ได้ว่าจะคัดลอกจำนวนเท่าใด
เวอร์ชันของdd
ใน GNU coreutils (ตามที่พบใน Linux ที่ไม่ได้ฝังตัวและบน Cygwin) มีการตั้งค่าสถานะfullblock
ซึ่งบอกdd
ให้เรียกใช้read
ในลูป (และเหมือนกันสำหรับwrite
) และจึงถ่ายโอนบล็อกเต็มเสมอ ข้อความแสดงข้อผิดพลาดแสดงให้เห็นว่าคุณใช้มัน คุณควรใช้มัน (ทั้งในอินพุตและแฟล็กเอาท์พุท) ยกเว้นในกรณีพิเศษมาก (ส่วนใหญ่เมื่อเข้าถึงเทป) - ถ้าคุณใช้dd
เลยนั่นคือ: มักจะมีวิธีแก้ปัญหาที่ดีกว่า (ดูด้านล่าง)
dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000
อีกวิธีที่เป็นไปได้เพื่อให้แน่ใจว่าสิ่งที่dd
จะทำคือการส่งขนาดบล็อก 1 จากนั้นคุณสามารถบอกได้ว่ามีกี่ไบต์ที่ถูกคัดลอกจากการนับจำนวนบล็อก แต่ฉันไม่แน่ใจว่าจะเกิดอะไรขึ้นถ้า a read
ถูกขัดจังหวะก่อนอ่านครั้งแรก ไบต์ (ซึ่งไม่น่าเป็นไปได้ในทางปฏิบัติ แต่สามารถเกิดขึ้นได้) อย่างไรก็ตามแม้ว่ามันจะทำงานได้ช้ามาก
คำแนะนำทั่วไปเกี่ยวกับการใช้dd
มีที่ไม่ได้ใช้ dd
แม้ว่าdd
โฆษณามักจะเป็นคำสั่งระดับต่ำในการเข้าถึงอุปกรณ์ แต่ในความเป็นจริงแล้วไม่มีสิ่งดังกล่าว: ความมหัศจรรย์ทั้งหมดที่เกิดขึ้นในไฟล์อุปกรณ์ ( /dev/…
ส่วน) dd
เป็นเพียงเครื่องมือธรรมดาที่มีศักยภาพสูงสำหรับการใช้งานในทางที่ผิด . ในกรณีส่วนใหญ่มีวิธีที่ง่ายและปลอดภัยกว่าในการทำสิ่งที่คุณต้องการอย่างน้อยใน Linux
ตัวอย่างเช่นในการอ่านจำนวนไบต์ที่จุดเริ่มต้นของไฟล์เพียงโทรhead
:
head -c 1000000m </dev/urandom >file
ฉันทำมาตรฐานอย่างรวดเร็วในเครื่องของฉันและไม่ได้สังเกตเห็นความแตกต่างระหว่างการใด ๆที่มีขนาดใหญ่และบล็อกdd
head
หากคุณต้องการที่จะข้ามไบต์บางที่จุดเริ่มต้นท่อtail
ลงไปhead
:
dd if=input of=output count=C bs=B seek=S
<input tail -c +$((S*B+1)) | head -c $((C*B)) >output
หากคุณต้องการเห็นความคืบหน้าโทรlsof
เพื่อดูไฟล์ชดเชย ใช้งานได้กับไฟล์ปกติเท่านั้น (ไฟล์เอาต์พุตในตัวอย่างของคุณ) ไม่ใช่อุปกรณ์ตัวอักษร
lsof -a -p 1234 -d 1
cat /proc/1234/fdinfo/1
คุณสามารถโทรติดต่อpv
เพื่อรับรายงานความคืบหน้า (ดีกว่าdd
) ด้วยค่าใช้จ่ายของรายการเพิ่มเติมในไปป์ไลน์ (โดยคำนึงถึงประสิทธิภาพ