डीडी के साथ यादृच्छिक डेटा बनाएं और "आंशिक रूप से पढ़ने की चेतावनी" प्राप्त करें। क्या चेतावनी के बाद डेटा अब वास्तव में यादृच्छिक है?


16

मैं यादृच्छिक डेटा के साथ 1TB फ़ाइल बनाता हूं dd if=/dev/urandom of=file bs=1M count=1000000। अब मैं kill -SIGUSR1 <PID>प्रगति के साथ जाँच करता हूँ और निम्नलिखित प्राप्त करता हूँ:

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

मैं चेतावनी की व्याख्या नहीं कर सकता। यह क्या कहता है? क्या चेतावनी के बाद मेरी फ़ाइल वास्तव में यादृच्छिक है या कोई समस्या है? क्या +0 या +1 में करता है 800950+1 Datensätze einऔर 800950+0 Datensätze ausमतलब? चेतावनी के बाद यह +1 है। क्या यह एक त्रुटि है?


यदि आप संदेशों को अंग्रेजी में अनुवाद कर सकते हैं तो इसका जवाब देना आसान होगा। इसके अलावा, "वास्तव में यादृच्छिक" को परिभाषित करें। आपको किस स्तर की यादृच्छिकता की आवश्यकता है, आप इसके लिए क्या उपयोग करेंगे?
terdon

अंग्रेजी संदेश प्राप्त करने के लिए, LC_ALL=Cकमांड के सामने उपयोग करें , जैसेLC_ALL=C dd if=...
वोल्कर सेगेल

जवाबों:


38

सारांश: ddएक कर्कश उपकरण है जिसे सही ढंग से उपयोग करना मुश्किल है। कई ट्यूटोरियल के बावजूद इसका उपयोग न करें जो आपको ऐसा बताते हैं। ddइसके साथ एक "यूनिक्स स्ट्रीट क्रेड" वाइब है - लेकिन अगर आप वास्तव में समझ रहे हैं कि आप क्या कर रहे हैं, तो आप जानेंगे कि आपको इसे 10 फुट के पोल से नहीं छूना चाहिए।

ddreadसिस्टम कॉल प्रति ब्लॉक (मूल्य के द्वारा परिभाषित 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अब तक कॉपी किए गए हैं, जिस स्थिति में आप यह नहीं जान सकते कि यह कितने अधिक बाइट्स की नकल करेगा।

ddGNU कोरुटिल्स के संस्करण (जैसा कि गैर-एम्बेडेड लिनक्स और सिग्विन पर पाया जाता है) में एक झंडा fullblockहोता है जो लूप (और डिट्टो फॉर ) में ddकॉल करने के लिए कहता है और इस तरह हमेशा पूर्ण ब्लॉकों को स्थानांतरित करता है। त्रुटि संदेश बताता है कि आप इसका उपयोग करते हैं; आपको हमेशा इसका उपयोग करना चाहिए (इनपुट और आउटपुट फ्लैग दोनों में), बहुत विशेष परिस्थितियों को छोड़कर (ज्यादातर टेप एक्सेस करते समय) - यदि आप बिल्कुल भी उपयोग करते हैं, तो यह है: आमतौर पर बेहतर समाधान होते हैं (नीचे देखें)।readwritedd

dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000

एक और संभावित तरीका यह सुनिश्चित करने के लिए कि dd1. ब्लॉक का आकार पास करना क्या है। तब आप बता सकते हैं कि ब्लॉक गिनती से कितने बाइट्स कॉपी किए गए थे, हालांकि मुझे यकीन नहीं है कि अगर 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 से बेहतर ), पाइपलाइन में एक अतिरिक्त आइटम की कीमत पर (प्रदर्शन-वार, यह मुश्किल से बोधगम्य है)।


2
+1। यह सबसे अच्छी तरह से शोध किए गए पदों में से एक है जो मैंने लंबे समय में स्टैकएक्सचेंज नेटवर्क पर पढ़ा है। यह संक्षिप्त है, फिर भी ddकमांड के बारे में सभी विवरण (ऐतिहासिक और वर्तमान) शामिल हैं जो मुझे नहीं पता था कि मुझे पता होना चाहिए। धन्यवाद।
कॉस्मिक ओस्सिफ्रेज

4
मुझे खेद है लेकिन मैं आपके दावे से असहमत हूं कि dd एक "क्रेंकी टूल है जो सही तरीके से उपयोग करना कठिन है" और "dd का उपयोग न करें"। यह एक पूरी तरह से ठीक उपयोगिता है जब किसी व्यक्ति द्वारा सही ढंग से उपयोग किया जाता है जिसने इसे समझने के लिए समय लिया है। वास्तव में डिस्क फोरेंसिक टूलकिट लगभग सभी dd या एक व्युत्पन्न जैसे dcfldd पर निर्भर करते हैं।
fpmurphy

1
@ fpmurphy1 GNU का ddसुरक्षित रूप से उपयोग किया जा सकता है, इसके fullblockविकल्प के लिए धन्यवाद । लेकिन अगर आपके पास जीएनयू कोरुटिल्स हैं तो आपको ddज्यादा जरूरत नहीं है । "डेरिवेटिव" जैसे कि dcflddवे नहीं हैं dd , वे इसके डिजाइन दोष से पीड़ित नहीं हैं, इसलिए मेरा जवाब उन पर लागू नहीं होता है। उपयोग करने वाले एक विशाल, विशाल बहुमत ने ddइसे समझने के लिए पर्याप्त समय नहीं लिया है (अधिकतम, उन्होंने यह सोचने के लिए समय लिया है कि वे इसे समझते हैं) और जिस तरह से वे इसका उपयोग करते हैं, उससे डेटा हानि होती है।
गिलेस एसओ- बुराई को रोकना '

1
@ गाइल्स तो हमें दुरुपयोग के लिए अपनी क्षमता के "इको" बी / सी का उपयोग नहीं करना चाहिए (sudo echo hello world> / dev / sda)?
व्हाइटी 04

2
@ whitey04 मैं नाइट्रोग्लिसरीन के बैरल को संभालने की सलाह नहीं देता। मैंने यह नहीं कहा कि आपको मैचों का उपयोग नहीं करना चाहिए।
गिल्स एसओ- बुराई को रोकें '

9

चेतावनी तब होती है जब ddएक ही रीड में ब्लॉक भरने के लिए पर्याप्त डेटा नहीं मिल पाता। यह अनियमित या धीमे डेटा स्रोतों, या स्रोतों के साथ होता है जो आपके अनुरोधित अवरोधन की तुलना में छोटी इकाइयों में डेटा लिखते हैं।

डेटा अखंडता के साथ कोई समस्या नहीं है, लेकिन समस्या यह है कि ddएक आंशिक रूप से पढ़े गए ब्लॉक को अभी भी एक रीड ब्लॉक के रूप में गिना जाता है।

यदि आप countविकल्प का उपयोग नहीं कर रहे हैं , तो चेतावनी शायद ही मायने रखती है, यह सिर्फ एक प्रदर्शन पर विचार है। लेकिन count, आपके द्वारा अनुरोधित डेटा की मात्रा नहीं मिलेगी। आंशिक पठन के कारण, अंत में ofसे छोटा होगा count*bs

इसलिए जब आप उपयोग करते हैं count, तो तकनीकी रूप से आपको हमेशा उपयोग करना चाहिए iflag=fullblock

+xआंशिक ब्लॉक की संख्या होना चाहिए।


-3
< /dev/urandom \
dd ibs=4k obs=64k |
dd bs=64k count=16000000 >file

^ वह सिर्फ काम करेगा। अन्यथा गलत जानकारी यहाँ प्रकट रूप से झूठी थी। ddबफ़र्स स्पष्ट हैं और इसलिए, उन घटनाओं को गिनने के लिए बफर इनपुट के लिए जिन्हें आपको स्पष्ट रूप से बफर करने की आवश्यकता है। बस इतना ही। फड मत खरीदो।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.