dd 1 GB के बजाय 32 MB रैंडम फ़ाइल का उत्पादन कर रहा है


50

मैं 1 जीबी रैंडम फ़ाइल का उत्पादन करना चाहता था, इसलिए मैंने निम्नलिखित कमांड का उपयोग किया।

dd if=/dev/urandom of=output bs=1G count=1

लेकिन हर बार जब मैं इस कमांड को लॉन्च करता हूं तो मुझे एक 32 एमबी फाइल मिलती है:

<11:58:40>$ dd if=/dev/urandom of=output bs=1G count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB, 32 MiB) copied, 0,288321 s, 116 MB/s

गलत क्या है?

संपादित करें:

इस विषय में महान जवाब के लिए धन्यवाद मैं समाधान के साथ आया जो 32 चंक्स 32 एमबी बड़े पढ़ता है जो 1 जीबी बनाता है:

dd if=/dev/urandom of=output bs=32M count=32

अन्य समाधान दिया गया था कि मेमोरी में 1 जीबी सीधे पढ़ता है और फिर डिस्क पर लिखता है। इस समाधान में बहुत अधिक मेमोरी होती है इसलिए यह पहले से मौजूद नहीं है:

dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock

3
IMHO मुझे नहीं लगता कि ddसभी के लिए कई वैध उपयोग के मामले हैं । मैं उपयोग करता हूँ head, catया rsyncइसकी जगह पर लगभग हमेशा। और आपका सवाल है कि क्या कारणों में से एक विकल्प आमतौर पर सुरक्षित हैं।
बकुरीउ

@ बकुरीउ - अगर आप सिर्फ जीरो से भरी फाइल का उत्पादन करना चाहते हैं (या इसके बजाय आपको इस बात की परवाह नहीं है कि इसके अंदर क्या है) ट्रंकट का उपयोग करें। यह बहुत तेज है।
कोनराड गजवेस्की

@KonradGajewski FYI ट्रंकट एक विरल फ़ाइल बनाने की कोशिश करता है (यदि वह मायने रखता है)
Xen2050

5
@Bakuriu headयह कार्य बिना उस -cविकल्प के नहीं कर सकता जो POSIX में नहीं है । मुझे नहीं पता कि इसका कोई भी संस्करण catइसका समाधान कर सकता है। rsyncएक पूरी तरह से गैरमानक उपयोगिता है। वह न तो यहां nr है; अपने मैन पेज के माध्यम से स्किमिंग, मैं यह नहीं देखता कि यह इस समस्या को कैसे हल कर सकता है।
कज़

तकनीकी रूप से, /dev/urandomPOSIX में नहीं है ...
grawity

जवाबों:


92

bs, बफर आकार, का अर्थ है dd द्वारा किया गया एकल रीड () कॉल का आकार ।

(उदाहरण के लिए, दोनों bs=1M count=1और bs=1k count=1kएक 1 MiB फ़ाइल में परिणाम होगा, लेकिन पहले संस्करण एक ही चरण में यह करना होगा, जबकि दूसरा 1024 छोटे-छोटे टुकड़ों में कर देगा।)

नियमित फ़ाइलों को लगभग किसी भी बफर आकार में पढ़ा जा सकता है (जब तक कि बफर रैम में फिट बैठता है), लेकिन डिवाइस और "वर्चुअल" फाइलें अक्सर व्यक्तिगत कॉल के बहुत करीब काम करती हैं और कुछ मनमाना प्रतिबंध लगाती हैं कि वे कितने डेटा का उत्पादन करेंगे। पढ़ा () कॉल।

के लिए /dev/urandom, इस सीमा को ड्राइवरों / char / random.c में urandom_read () में परिभाषित किया गया है :

#define ENTROPY_SHIFT 3

static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
    nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
    ...
}

इसका मतलब यह है कि हर बार फ़ंक्शन को कॉल किया जाता है, यह अनुरोधित आकार को 33554431 बाइट्स से जकड़ देगा।

डिफ़ॉल्ट रूप से, अधिकांश अन्य उपकरणों के विपरीत, dd अनुरोध से कम डेटा प्राप्त करने के बाद फिर से प्रयास नहीं करेगा - आपको 32 MiB मिलता है और यह है। (कामिल के उत्तर के अनुसार, इसे स्वचालित रूप से पुन: प्रयास करने के लिए, आपको निर्दिष्ट करना होगा iflag=fullblock।)


यह भी ध्यान दें कि "एकल रीड () का आकार" का अर्थ है कि पूरे बफर को एक बार में मेमोरी में फिट होना चाहिए, इसलिए बड़े पैमाने पर ब्लॉक आकार भी dd द्वारा बड़े पैमाने पर मेमोरी के उपयोग के अनुरूप हैं ।

और यह सब व्यर्थ है क्योंकि आप आमतौर पर किसी भी प्रदर्शन को प्राप्त नहीं करेंगे जब ~ 16-32 MiB ब्लॉक से ऊपर जा रहा है - syscalls यहाँ धीमा हिस्सा नहीं है, यादृच्छिक संख्या जनरेटर है।

तो सादगी के लिए, बस उपयोग करें head -c 1G /dev/urandom > output


7
"- आप आमतौर पर ~ 16-32 मिब ब्लॉक से ऊपर जाने पर कोई प्रदर्शन हासिल नहीं करेंगे" - मेरे अनुभव में, आप बहुत अधिक लाभ नहीं उठाते हैं, या 64-128 किलो बाइट के ऊपर भी प्रदर्शन नहीं खोते हैं । उस बिंदु पर, आप घटते हुए रिट wrt syscall लागत में अच्छी तरह से हैं, और कैश विवाद एक भूमिका निभाने के लिए शुरू होता है।
मार्सेल्म

3
@marcelm मैंने आर्किटेक्ट उच्च प्रदर्शन प्रणालियों में मदद की है जहां IO का प्रदर्शन बेहतर होगा क्योंकि ब्लॉक आकार 1-2 एमबी ब्लॉक तक बढ़ जाता है, और कुछ मामलों में 8 एमबी तक बढ़ जाता है। प्रति लुन। और जैसा कि कई समानांतर LUN का उपयोग करके फाइलसिस्टम का निर्माण किया गया था, IO के लिए कई थ्रेड्स का उपयोग करते हुए सर्वश्रेष्ठ प्रदर्शन प्राप्त करने के लिए, प्रत्येक 1 MB + ब्लॉक कर रहा है। निरंतर IO दरें 1 GB / सेकंड से अधिक थीं। और वे सभी कताई डिस्क थे, इसलिए मैं एसएसडी के उच्च-प्रदर्शन सरणियों को डेटा को तेजी से और तेजी से निगलने या उत्पन्न करने में देख सकता हूं क्योंकि ब्लॉक आकार 16 या 32 एमबी ब्लॉक तक बढ़ता है। सरलता। शायद और भी बड़ा।
एंड्रयू हेनले

4
मैं स्पष्ट रूप से ध्यान देता हूँ कि POSIX उपयोगिता केiflag=fullblock लिए एक GNU एक्सटेंशन है । जैसा कि प्रश्न लिनक्स को निर्दिष्ट नहीं करता है, मुझे लगता है कि लिनक्स-विशिष्ट एक्सटेंशन के उपयोग को संभवतः स्पष्ट रूप से नोट किया जाना चाहिए ताकि कुछ भविष्य के पाठक गैर-लिनक्स सिस्टम पर एक समान समस्या को हल करने की कोशिश कर सकें। dd
एंड्रयू हेनले

6
@AndrewHenle आह, दिलचस्प! मैंने ddअपनी मशीन पर 1k से 512M तक ब्लॉक आकार के साथ एक त्वरित परीक्षण किया । एक इंटेल 750 एसएसडी से पढ़ना, इष्टतम प्रदर्शन (लगभग 1300MiB / s) 2MiB ब्लॉकों में प्राप्त किया गया था, मोटे तौर पर आपके परिणामों से मेल खाता था। बड़े ब्लॉक आकार ने न तो मदद की और न ही बाधा। से पढ़ रहा है /dev/zero, अनुकूलतम प्रदर्शन (लगभग 20GiB / s) 64KiB और 128KiB ब्लॉकों में किया गया था, दोनों छोटे और बड़े ब्लॉकों ने प्रदर्शन में कमी की, मेरी पिछली टिप्पणी से मोटे तौर पर मिलान किया। नीचे पंक्ति: अपनी वास्तविक स्थिति के लिए बेंचमार्क। और हां, हम दोनों में से कोई भी बेंचमार्क नहीं है /dev/random: P
marcelm

3
@ Xen2050 मैंने कुछ और त्वरित परीक्षण किए, और ऐसा प्रतीत होता ddहै कि यह तेज है। एक त्वरित headस्ट्रेस से पता चला कि इसमें 8KiB रीड का उपयोग किया गया है, और दो 4KiB लिखते हैं, जो दिलचस्प है (डेबियन 9.6 / लिनक्स 4.8 पर GNU कोरुटिल 8.26)। headगति वास्तव में कहीं dd bs=4kऔर के बीच में हैं dd bs=8kheadगति ~ 40% की तुलना में dd if=/dev/zero bs=64kनीचे और ~ 25% की तुलना में नीचे हैं dd if=/dev/nvme0n1 bs=2M। से पढ़ता /dev/zeroबेशक अधिक सीपीयू-सीमित है, लेकिन SSD I / O के लिए भी एक भूमिका निभाता है। यह मेरी अपेक्षा से बहुत बड़ा अंतर है।
मार्सेल्म

21

ddसे कम पढ़ा जा सकता है ibs(ध्यान दें: bsदोनों निर्दिष्ट करता है ibsऔर obs), जब तक iflag=fullblockकि निर्दिष्ट न हो। 0+1 records inइंगित करता है कि 0पूर्ण ब्लॉक और 1आंशिक ब्लॉक पढ़ा गया था। हालांकि कोई भी पूर्ण या आंशिक ब्लॉक काउंटर को बढ़ाता है।

मैं उस सटीक तंत्र को नहीं जानता जो ddएक ब्लॉक को पढ़ता है जो 1Gइस विशेष मामले से कम है । मुझे लगता है कि किसी भी ब्लॉक को पढ़ने से पहले मेमोरी में पढ़ा जाता है, इसलिए मेमोरी प्रबंधन हस्तक्षेप कर सकता है (लेकिन यह केवल एक अनुमान है)। संपादित करें: यह समवर्ती उत्तर उस तंत्र की व्याख्या करता है जो ddएक ब्लॉक को पढ़ता है जो 1Gइस विशेष मामले से कम है ।

वैसे भी, मैं इतनी बड़ी सलाह नहीं देता bs। मैं उपयोग करूंगा bs=1M count=1024। सबसे महत्वपूर्ण बात यह है: बिना iflag=fullblock किसी पढ़े हुए प्रयास से कम पढ़ा जा सकता है ibs(जब तक ibs=1, मुझे नहीं लगता, यह हालांकि काफी अक्षम है)।

इसलिए यदि आपको कुछ सटीक डेटा पढ़ने की आवश्यकता है, तो उपयोग करें iflag=fullblock। नोट iflagPOSIX द्वारा आवश्यक नहीं है, आपका ddसमर्थन इसका समर्थन नहीं कर सकता है। इस उत्तर के अनुसार ibs=1बाइट्स की सटीक संख्या को पढ़ने के लिए संभवतः एकमात्र POSIX तरीका है। बेशक यदि आप बदलते हैं ibsतो आपको पुनर्गणना करने की आवश्यकता होगी count। आपके मामले में कम करने ibsके लिए 32Mया उससे कम शायद बिना, इस मुद्दे को ठीक होगा iflag=fullblock

मेरे कुबंटु में मैं आपकी आज्ञा को इस तरह तय करूंगा:

dd if=/dev/urandom of=output bs=1M count=1024 iflag=fullblock
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.