Dd डेटा कॉपी करने के लिए उपयुक्त कब है? (या, जब पढ़ा जाता है) और (आंशिक) लिखें


60

लघु संस्करण:dd डेटा की प्रतिलिपि बनाने के लिए किन परिस्थितियों में उपयोग करना सुरक्षित है, सुरक्षित अर्थ है कि आंशिक रूप से पढ़ने या लिखने के कारण भ्रष्टाचार का कोई खतरा नहीं है?

लंबे संस्करण - प्रस्तावना: dd अक्सर डेटा की प्रतिलिपि बनाने के लिए उपयोग किया जाता है, विशेष रूप से या एक उपकरण ( उदाहरण ) से। यह कभी-कभी अन्य उपकरणों की तुलना में निचले स्तर पर उपकरणों का उपयोग करने में सक्षम होने के रहस्यमय गुणों को जिम्मेदार ठहराता है (जब वास्तव में यह डिवाइस फ़ाइल है जो जादू कर रहा है) - फिर भी dd if=/dev/sdaजैसा है वैसा ही है cat /dev/sdaddकभी-कभी तेज़ माना जाता है, लेकिन catव्यवहार में इसे हरा सकते हैं । बहरहाल, ddइसमें अद्वितीय गुण हैं जो इसे कभी-कभी उपयोगी बनाते हैं

समस्या: dd if=foo of=bar वास्तव में, के रूप में ही नहीं है cat <foo >bar। अधिकांश यूनिटो पर, ddएकल कॉल करता है read()। (मुझे लगता है कि "एक इनपुट ब्लॉक को पढ़ने" का गठन करने पर पोस्ज़ फ़ज़ी लगता है dd।) यदि read()आंशिक परिणाम देता है (जो कि, POSIX और अन्य संदर्भ दस्तावेज़ों के अनुसार, तो यह अनुमति दी जाती है जब तक कि कार्यान्वयन दस्तावेज़ अन्यथा नहीं कहता), एक आंशिक ब्लॉक की प्रतिलिपि बनाई जाती है। वास्तव में एक ही समस्या के लिए मौजूद है write()

अवलोकन : व्यवहार में, मैंने पाया है कि ddब्लॉक डिवाइस और नियमित फ़ाइलों के साथ सामना कर सकता है, लेकिन यह सिर्फ यह हो सकता है कि मैंने इसे बहुत अधिक अभ्यास नहीं किया है। जब पाइप की बात आती है, तो ddगलती करना मुश्किल नहीं है; उदाहरण के लिए इस कोड को आज़माएं :

yes | dd of=out bs=1024k count=10

और outफ़ाइल का आकार जांचें (यह 10 एमबी से कम होने की संभावना है)।

प्रश्न : ddडेटा की प्रतिलिपि बनाने के लिए किन परिस्थितियों में उपयोग करना सुरक्षित है? दूसरे शब्दों में, फ़ाइल के प्रकार, आदि पर, ब्लॉक आकार पर क्या शर्तें लागू होती हैं, यह सुनिश्चित कर सकता है कि ddसभी डेटा को कॉपी करेगा?

( GNU dd के पास fullblockयह बताने के लिए read()या write()लूप में कॉल करने के लिए एक ध्वज है ताकि एक पूर्ण ब्लॉक को स्थानांतरित किया जा सके। इसलिए dd iflag=fullblockहमेशा सुरक्षित रहता है। मेरा प्रश्न उस मामले के बारे में है जब ये झंडे (जो अन्य कार्यान्वयन पर मौजूद नहीं हैं) का उपयोग नहीं किया जाता है। ।)

¹ मैंने ओपनबीएसडी, जीएनयू कोरयूटिल्स और बिजीबॉक्स पर जाँच की है।


मैंने कभी कोई यूनिक्स सिस्टम नहीं देखा है जो वास्तव में एक ही रीड (2) में कुछ MiB को पढ़ सके ...
vonbrand

3
उपयोग करते समय count, iflag=fullblockअनिवार्य है (या वैकल्पिक रूप से iflag=count_bytes)। नहीं है oflag=fullblock
ठंढकुट्ज़

जवाबों:


10

से कल्पना :

  • तो bs=exprसंकार्य निर्दिष्ट किया जाता है और बिना किसी रूपांतरण के अलावा अन्य sync, noerrorया notruncअनुरोध कर रहे हैं, डेटा प्रत्येक इनपुट ब्लॉक से लौटे एक अलग उत्पादन ब्लॉक के रूप में लिखा जाएगा; यदि read()पूर्ण ब्लॉक और syncरूपांतरण से कम रिटर्न निर्दिष्ट नहीं है, तो परिणामी आउटपुट ब्लॉक इनपुट ब्लॉक के समान आकार का होगा।

तो शायद यही आपके भ्रम का कारण बनता है। हाँ, क्योंकि ddहै डिज़ाइन किया गया अवरुद्ध, डिफ़ॉल्ट रूप से आंशिक के लिए read()आंशिक करने के लिए 1: रों 1 मैप किया जाएगा write()रों, वरना syncकरने पर पूंछ गद्दी NUL या अंतरिक्ष वर्ण बाहर d bs=जब आकार conv=syncनिर्दिष्ट किया जाता है।

इसका मतलब है कि ddहै (w / भ्रष्टाचार का कोई खतरा नहीं एक आंशिक पढ़ने या लिखने की वजह से) नकल डेटा के लिए उपयोग करने के लिए सुरक्षित हर मामले में, लेकिन एक है जिसमें यह मनमाने ढंग से एक द्वारा सीमित है count=तर्क, क्योंकि अन्यथा ddहोगा खुशी से write()हूबहू आकार ब्लॉकों में इसके उत्पादन उन लोगों के लिए जिसमें इसका इनपुट तब read()तक था जब तक कि यह read()पूरी तरह से इसके माध्यम से न हो। और यहां तक कि इस चेतावनी है ही सच्चा जब bs=निर्दिष्ट किया जाता है या obs=है नहीं निर्दिष्ट, कल्पना राज्यों में अगले ही वाक्य के रूप में:

  • तो bs=exprसंकार्य निर्दिष्ट नहीं है, या एक रूपांतरण के अलावा अन्य sync, noerrorया notruncअनुरोध किया जाता है, इनपुट संसाधित किया जाएगा और पूर्ण आकार उत्पादन ब्लॉक में एकत्र जब तक इनपुट के अंत तक पहुँच गया है।

बिना ibs=और / या obs=तर्क के यह कोई फर्क नहीं पड़ता - क्योंकि ibsऔर obsडिफ़ॉल्ट रूप से एक ही आकार के हैं। हालाँकि, आप इनपुट बफ़रिंग के बारे में अलग-अलग आकार निर्दिष्ट करके स्पष्ट कर सकते हैं या तो निर्दिष्ट नहीं कर सकते (क्योंकि इसमें पूर्वता लगती है)bs=

उदाहरण के लिए, यदि आप करते हैं:

IN| dd ibs=1| OUT

... तो एक एकल उत्पादन ब्लॉक में हर एकल बाइट को इकट्ठा करके 512 बाइट्स का हिस्सा ddहोगा ।write()read()

अन्यथा, यदि आप करते हैं ...

IN| dd obs=1kx1k| OUT

... एक POSIX एक समय में अधिकतम 512 बाइट्स पर ddहोगा , लेकिन प्रत्येक मेगाबाइट-आकार के आउटपुट ब्लॉक (कर्नेल को अनुमति देने और संभवतः अंतिम को छोड़कर - क्योंकि वह ईओएफ है) पूर्ण-आकार वाले आउटपुट ब्लॉक में इनपुट एकत्र करके ।read() write()

हालांकि कल्पना से, हालांकि:

  • count=n
    • केवल n इनपुट ब्लॉक कॉपी करें ।

count=i?bs=ब्लॉक करने के लिए नक्शे , और इसलिए count=आप दो ddएस की आवश्यकता होगी पर एक मनमानी सीमा को संभालने के लिए । दो ddएस के साथ यह करने का सबसे व्यावहारिक तरीका एक के आउटपुट को दूसरे के इनपुट में पाइप करके है, जो निश्चित रूप से मूल इनपुट प्रकार की परवाह किए बिना एक विशेष फ़ाइल को पढ़ने / लिखने के दायरे में रखता है ।

एक आईपीसी पाइप का मतलब है कि जब यह निर्दिष्ट करता है [io]bs=कि सुरक्षित रूप से ऐसा करने के लिए, आपको सिस्टम की निर्धारित PIPE_BUFसीमा के भीतर ऐसे मूल्यों को रखना चाहिए । POSIX कहा गया है कि सिस्टम कर्नेल केवल परमाणु गारंटी चाहिए read()और write()की सीमाओं के भीतर रों PIPE_BUFके रूप में परिभाषित किया limits.h। POSIX गारंटी देता है कि PIPE_BUFहो सकता है कम से कम ...

  • {_POSIX_PIPE_BUF}
    • पाइप से लिखते समय अधिकतम बाइट्स जो परमाणु होने की गारंटी है।
    • मान: 512

... (जो डिफॉल्ट ddi / o blockize होना भी होता है ) , लेकिन वास्तविक मूल्य कम से कम 4k है। एक अप-टू-डेट लिनक्स सिस्टम पर, यह डिफ़ॉल्ट रूप से, 64k है।

इसलिए जब आप अपनी ddप्रक्रियाओं को सेट करते हैं तो आपको इसे तीन मानों के आधार पर ब्लॉक कारक पर करना चाहिए :

  1. bs = (अवलोकन = PIPE_BUFया कम)
  2. n = बाइट्स की कुल वांछित संख्या पढ़ी गई
  3. गिनती = एन / बी एस

पसंद:

yes | dd obs=1k | dd bs=1k count=10k of=/dev/null
10240+0 records in
10240+0 records out
10485760 bytes (10 MB) copied, 0.1143 s, 91.7 MB/s

ddगैर-शोध योग्य जानकारी को संभालने के लिए आपको i / ow / को सिंक्रोनाइज़ करना होगा। दूसरे शब्दों में, पाइप-बफ़र्स को स्पष्ट करें और वे एक समस्या बन जाते हैं। वह किस ddलिए है? यहां अज्ञात मात्रा yesबफर का आकार है - लेकिन यदि आप इसे किसी अन्य के साथ ज्ञात मात्रा में ब्लॉक करते हैं, ddतो थोड़ा सूचित गुणन dd डेटा की प्रतिलिपि बनाने के लिए उपयोग करना सुरक्षित कर सकता है (आंशिक रूप से पढ़ने या लिखने के कारण भ्रष्टाचार का कोई जोखिम नहीं) यहां तक ​​कि जब मनमाने ढंग से इनपुट W / count=w / किसी भी POSIX सिस्टम पर किसी भी प्रकार के मनमाने इनपुट प्रकार को सीमित करने और एक भी बाइट को याद किए बिना।

यहाँ POSIX युक्ति से एक स्निपेट दिया गया है :

  • ibs=expr
    • इनपुट ब्लॉक आकार निर्दिष्ट करें, बाइट्स में, (डिफ़ॉल्ट रूप से 512) हैexpr
  • obs=expr
    • आउटपुट ब्लॉक आकार निर्दिष्ट करें, बाइट्स में, (डिफ़ॉल्ट रूप से 512) हैexpr
  • bs=expr
    • इनपुट और आउटपुट ब्लॉक आकार दोनों को exprबाइट्स, सुपरस्डिंग ibs=और पर सेट करें obs=। कोई रूपांतरण के अलावा अन्य हैं sync, noerrorऔर notruncनिर्दिष्ट किया जाता है, प्रत्येक इनपुट ब्लॉक कम ब्लॉक के योग के बिना एक भी ब्लॉक के रूप में उत्पादन में कॉपी किया जाएगा।

आप भी इस में से कुछ बेहतर समझाया मिल जाएगा यहाँ


5

सॉकेट, पाइप, या टिट्स के साथ, पढ़ा () और लिखें () अनुरोधित आकार से कम स्थानांतरित कर सकते हैं, इसलिए जब इन पर dd का उपयोग करते हैं, तो आपको फुलब्लॉक ध्वज की आवश्यकता होती है। हालाँकि, नियमित फ़ाइलों और ब्लॉक उपकरणों के साथ, केवल दो बार होते हैं जब वे एक छोटा रीड / राइट कर सकते हैं: जब आप ईओएफ तक पहुंचते हैं, या यदि कोई त्रुटि होती है। यही कारण है कि फुलब्लॉक ध्वज के बिना dd के पुराने कार्यान्वयन डिस्क दोहराव के लिए उपयोग करने के लिए सुरक्षित थे।


क्या यह सभी आधुनिक यूनियनों का सच है? (मुझे पता है कि यह कुछ बिंदु पर लिनक्स का सच नहीं था, संभवतः 2.0.x या 2.2.x तक। मैं mke2fsचुपचाप विफल हो रहा हूं क्योंकि यह write()कुछ गैर-शक्ति-में से 2 आकार (3kB IIRC) और कर्नेल के साथ कॉल करता है 2. की शक्ति के नीचे)
गिले

@ गिल्स जो पूरी तरह से एक अलग मुद्दे की तरह लग रहा है। आपको हमेशा ब्लॉक डिवाइस के साथ उचित ब्लॉक आकार के कई का उपयोग करना होगा। मुझे पूरा यकीन है कि यह सभी अशुद्धियों का सच है, और यह विंडोज़ के लिए भी सच है।
Psusi

टेप के अलावा, डिवाइस का ब्लॉक आकार पूरी तरह से कर्नेल की देखभाल के लिए है, या नहीं। cat </dev/sda >/dev/sdbडिस्क को क्लोन करने के लिए बस ठीक काम करता है।
गाइल्स

@ गिले इसलिए कि बिल्ली उपयुक्त ब्लॉक आकार का उपयोग करती है, जैसा कि उनके जवाब में OrbWeaver ने नोट किया है।
१५

नहीं, कोई "उपयुक्त ब्लॉक आकार" नहीं है। catप्रदर्शन के लिए एक बफर आकार चुनता है; इसे कर्नेल से कोई उपकरण-संबंधित जानकारी नहीं मिलती है। इसके अलावा टेप से, आप कर सकते हैं read()और write()किसी भी आकार के साथ एक ब्लॉक डिवाइस के लिए। कम से कम लिनक्स पर, st_blksizeकेवल उस फाइल सिस्टम पर निर्भर करता है जहां ब्लॉक डिवाइस इनोड स्थित है, अंतर्निहित डिवाइस पर नहीं।
जिल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.