सारांश: dd
एक कर्कश उपकरण है जिसे सही ढंग से उपयोग करना मुश्किल है। कई ट्यूटोरियल के बावजूद इसका उपयोग न करें जो आपको ऐसा बताते हैं। dd
इसके साथ एक "यूनिक्स स्ट्रीट क्रेड" वाइब है - लेकिन अगर आप वास्तव में समझ रहे हैं कि आप क्या कर रहे हैं, तो आप जानेंगे कि आपको इसे 10 फुट के पोल से नहीं छूना चाहिए।
dd
read
सिस्टम कॉल प्रति ब्लॉक (मूल्य के द्वारा परिभाषित bs
) के लिए एकल कॉल करता है । इस बात की कोई गारंटी नहीं है कि read
सिस्टम निर्दिष्ट बफर आकार जितना डेटा लौटाता है। यह नियमित फ़ाइलों और ब्लॉक उपकरणों के लिए काम करता है, लेकिन पाइप और कुछ चरित्र उपकरणों के लिए नहीं। देखें कि डीडी कब डेटा कॉपी करने के लिए उपयुक्त है? (या, जब पढ़े जाते हैं) और अधिक जानकारी के लिए () आंशिक लिखें । यदि read
सिस्टम कॉल एक पूर्ण ब्लॉक से कम रिटर्न देता है, तो dd
एक आंशिक ब्लॉक स्थानांतरित करता है। यह अभी भी ब्लॉकों की निर्दिष्ट संख्या की प्रतिलिपि बनाता है, इसलिए स्थानांतरित बाइट्स की कुल राशि अनुरोध से कम है।
"आंशिक रीड" के बारे में चेतावनी आपको वास्तव में यह बताती है: रीड्स में से एक आंशिक था, इसलिए dd
एक अपूर्ण ब्लॉक को स्थानांतरित कर दिया। ब्लॉक गणना में, +1
इसका मतलब है कि एक ब्लॉक आंशिक रूप से पढ़ा गया था; चूंकि आउटपुट काउंट होता है +0
, इसलिए सभी ब्लॉक पढ़े लिखे लिखे गए थे।
यह डेटा की यादृच्छिकता को प्रभावित नहीं करता है: जो सभी बाइट्स dd
लिखते हैं वे बाइट्स हैं जो इसे पढ़ते हैं /dev/urandom
। लेकिन आपको उम्मीद से कम बाइट्स मिलीं।
लिनक्स की /dev/urandom
मनमानी बड़े अनुरोधों (स्रोत: extract_entropy_user
में drivers/char/random.c
) को समायोजित करती है , इसलिए dd
इसे पढ़ने से आम तौर पर सुरक्षित है। हालांकि, बड़ी मात्रा में डेटा पढ़ने में समय लगता है। यदि प्रक्रिया एक संकेत प्राप्त करती है, तो read
सिस्टम अपने आउटपुट बफर को भरने से पहले रिटर्न को कॉल करता है । यह सामान्य व्यवहार है, और अनुप्रयोगों को read
एक लूप में कॉल करना है ; dd
ऐसा नहीं करता है, ऐतिहासिक कारणों से ( dd
'उत्पत्ति की उत्पत्ति घिनौनी है, लेकिन ऐसा लगता है कि इसे टेप तक पहुंचने के लिए एक उपकरण के रूप में शुरू किया गया है, जिसकी अजीबोगरीब आवश्यकताएं हैं, और इसे कभी भी सामान्य-प्रयोजन के उपकरण के रूप में अनुकूलित नहीं किया गया था)। जब आप प्रगति की जांच करते हैं, तो यह dd
प्रक्रिया को एक संकेत भेजता है जो रीड को बाधित करता है। आपके पास कितने बाइट्स हैं, यह जानने के बीच एक विकल्प हैdd
कुल में नकल करेंगे (यह सुनिश्चित करें कि इसे बाधित न करें - कोई प्रगति जांच, कोई निलंबन नहीं), या यह जानने के लिए कि कितने बाइट्स dd
अब तक कॉपी किए गए हैं, जिस स्थिति में आप यह नहीं जान सकते कि यह कितने अधिक बाइट्स की नकल करेगा।
dd
GNU कोरुटिल्स के संस्करण (जैसा कि गैर-एम्बेडेड लिनक्स और सिग्विन पर पाया जाता है) में एक झंडा fullblock
होता है जो लूप (और डिट्टो फॉर ) में dd
कॉल करने के लिए कहता है और इस तरह हमेशा पूर्ण ब्लॉकों को स्थानांतरित करता है। त्रुटि संदेश बताता है कि आप इसका उपयोग करते हैं; आपको हमेशा इसका उपयोग करना चाहिए (इनपुट और आउटपुट फ्लैग दोनों में), बहुत विशेष परिस्थितियों को छोड़कर (ज्यादातर टेप एक्सेस करते समय) - यदि आप बिल्कुल भी उपयोग करते हैं, तो यह है: आमतौर पर बेहतर समाधान होते हैं (नीचे देखें)।read
write
dd
dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000
एक और संभावित तरीका यह सुनिश्चित करने के लिए कि dd
1. ब्लॉक का आकार पास करना क्या है। तब आप बता सकते हैं कि ब्लॉक गिनती से कितने बाइट्स कॉपी किए गए थे, हालांकि मुझे यकीन नहीं है कि अगर read
पहले पढ़ने से पहले एक बाधित हो जाए तो क्या होगा? बाइट (जो अभ्यास में बहुत संभावना नहीं है लेकिन हो सकता है)। हालांकि, भले ही यह काम करता है, यह बहुत धीमा है।
का उपयोग करने पर सामान्य सलाह dd
है का उपयोग नहीं करतेdd
। हालांकि dd
अक्सर उपकरणों तक पहुंचने के लिए एक निम्न-स्तरीय कमांड के रूप में विज्ञापित किया जाता है, यह वास्तव में ऐसी कोई बात नहीं है: सभी जादू डिवाइस फ़ाइल ( /dev/…
) भाग में होता है, dd
दुरुपयोग के लिए एक उच्च क्षमता के साथ सिर्फ एक साधारण उपकरण है जिसके परिणामस्वरूप डेटा हानि होती है । ज्यादातर मामलों में, एक सरल और सुरक्षित तरीका है कि आप क्या चाहते हैं, कम से कम लिनक्स पर।
उदाहरण के लिए, फ़ाइल की शुरुआत में एक निश्चित संख्या में बाइट्स पढ़ने के लिए, बस कॉल करें 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
's से बेहतर ), पाइपलाइन में एक अतिरिक्त आइटम की कीमत पर (प्रदर्शन-वार, यह मुश्किल से बोधगम्य है)।