ডেটা কখন অনুলিপি করার উপযুক্ত? (বা, কখন পড়বে () এবং লিখুন () আংশিক)


60

সংক্ষিপ্ত সংস্করণ: কোন পরিস্থিতিতে ddডেটা অনুলিপি করার জন্য নিরাপদ, নিরাপদ অর্থ আংশিক পড়া বা লেখার কারণে দুর্নীতির ঝুঁকি নেই?

দীর্ঘ সংস্করণ - উপস্থাপন: dd প্রায়শই ডেটা অনুলিপি করতে ব্যবহৃত হয়, বিশেষত কোনও ডিভাইস থেকে বা উদাহরণে ( উদাহরণস্বরূপ )। এটি কখনও কখনও অন্যান্য সরঞ্জামের তুলনায় নিম্ন স্তরে ডিভাইসগুলি অ্যাক্সেস করতে সক্ষম হওয়ার রহস্যময় বৈশিষ্ট্যগুলির জন্য দায়ী করা হয় (যখন বাস্তবে এটি যাদুটি করছে এমন ডিভাইস ফাইল) - তবে dd if=/dev/sdaএকই জিনিস cat /dev/sdaddকখনও কখনও দ্রুত বলে মনে হয়, তবে catএটি অনুশীলনে পরাজিত করতে পারে । তবুও, ddএর অনন্য বৈশিষ্ট্য রয়েছে যা এটি কখনও কখনও সত্যিকারের উপযোগী করে তোলে

সমস্যা: dd if=foo of=bar আসলে বাস্তবে একই রকম নয় cat <foo >bar। বেশিরভাগ unices¹ এ, ddএকটি কল করে read()। (আমি "ইনপুট ব্লকটি পড়া" এর মধ্যে পসিএক্সকে অস্পষ্ট মনে করি dd)) যদি read()কোনও আংশিক ফলাফল (যা পসিএক্স এবং অন্যান্য রেফারেন্স ডকুমেন্ট অনুসারে, বাস্তবায়ন ডকুমেন্টেশন অন্যথায় না বলে থাকে তবে) এটির অনুমতি দেয়, আংশিক ব্লকটি অনুলিপি করা হয় না। ঠিক একই সমস্যার জন্য বিদ্যমান write()

পর্যবেক্ষণ : অনুশীলনে, আমি খুঁজে পেয়েছি যে ddব্লক ডিভাইস এবং নিয়মিত ফাইলগুলি মোকাবেলা করতে পারে তবে কেবল এটি হতে পারে যে আমি এটি খুব বেশি ব্যবহার করে নি। যখন পাইপগুলির কথা আসে, তখন ddদোষ চাপানো কঠিন নয় ; উদাহরণস্বরূপ এই কোড চেষ্টা করুন :

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

এবং outফাইলটির আকার পরীক্ষা করুন (এটি সম্ভবত 10 এমবি এর চেয়ে ভাল হবে)।

প্রশ্ন : কোন পরিস্থিতিতে ddডেটা অনুলিপি করার জন্য ব্যবহার করা নিরাপদ? অন্য কথায়, ব্লকের আকারের, বাস্তবায়নের উপর, ফাইলের ধরণের ক্ষেত্রে কী কী অবস্থা ইত্যাদি নিশ্চিত করতে পারে যে ddসমস্ত ডেটা অনুলিপি করবে?

( জিএনইউ ডিডি-fullblock তে ফোন করতে read()বা write()একটি লুপে বলার জন্য একটি পতাকা রয়েছে যাতে একটি পূর্ণ ব্লক স্থানান্তর করতে পারে So dd iflag=fullblockতাই সর্বদা নিরাপদ My আমার প্রশ্নটি সেই ক্ষেত্রে যখন এই পতাকাগুলি (যা অন্যান্য বাস্তবায়নে বিদ্যমান নেই) ব্যবহৃত হয় না about ।)

Open আমি ওপেনবিএসডি, জিএনইউ কোর্টিলস এবং ব্যাসিবক্সে পরীক্ষা করেছি।


আমি এমন কোনও ইউনিক্সি সিস্টেম দেখিনি যা সত্যিই একক
পাঠে কয়েকটি এমআইবি

3
ব্যবহার করার সময় count, iflag=fullblockবাধ্যতামূলক (বা, বিকল্পভাবে iflag=count_bytes)। নেই oflag=fullblock
frostschutz

উত্তর:


10

বৈশিষ্ট থেকে :

  • তাহলে bs=exprপ্রতীক উল্লেখ করা হয় এবং কোন ধর্মান্তর ছাড়া অন্য sync, noerrorঅথবা notruncঅনুরোধ করা হয়, ডাটা প্রতিটি ইনপুট ব্লক থেকে ফিরে একটি পৃথক আউটপুট ব্লক হিসেবে লেখা যেতে হইবে; যদি read()পুরো ব্লকের চেয়ে কম রিটার্ন দেয় এবং syncরূপান্তরটি নির্দিষ্ট না করা হয়, ফলস্বরূপ আউটপুট ব্লকটি ইনপুট ব্লকের সমান আকারের হবে।

সুতরাং এটি সম্ভবত আপনার বিভ্রান্তির কারণ। হ্যাঁ, কারণ ddহয় পরিকল্পিত ব্লক, ডিফল্ট অনুসারে আংশিক জন্য read()আংশিক 1: S 1 ম্যাপ করা হবে write()গুলি, বা অন্য syncউপর লেঙ্গুড় প্যাডিং NUL বা স্থান অক্ষর আউট ঘ bs=যখন আকার conv=syncনির্দিষ্ট করা হয়েছে।

এর অর্থ এটি প্রতিটি ddক্ষেত্রে ডেটা অনুলিপি করার জন্য ব্যবহার করা নিরাপদ (ডাব্লু / আংশিক পড়া বা লেখার কারণে দুর্নীতির ঝুঁকি নেই) তবে এটি একটি count=যুক্তি দ্বারা নির্বিচারে সীমাবদ্ধ , কারণ অন্যথায় ddআনন্দের সাথে write()এটির আকারটি একই আকারের ব্লকগুলিতে আসবে এটির সম্পূর্ণরূপে read()না আসা পর্যন্ত যার মধ্যে এটির ইনপুট ছিল read()। এমনকি এই সতর্কীকরণ হয় একমাত্র সত্য যখন bs=নির্দিষ্ট করা বা obs=হয় না নির্দিষ্ট বৈশিষ্ট রাজ্যে ঠিক পরের বাক্য হিসাবে:

  • তাহলে bs=exprপ্রতীক নির্দিষ্ট করা না থাকে, অথবা একটি রূপান্তর ছাড়া অন্য sync, noerrorঅথবা notruncঅনুরোধ, ইনপুট প্রক্রিয়া হলে এবং দেখার হইবে পূর্ণ আকারের আউটপুট ব্লক মধ্যে সংগৃহীত পর্যন্ত ইনপুটের শেষে পৌঁছে গেছেন করা হয়।

ibs=এবং এবং বা obs=যুক্তি ছাড়া এটি কোনও বিষয় নয় - কারণ ibsএবং obsউভয়ই ডিফল্টরূপে একই আকার। তবে আপনি উভয়ের জন্য বিভিন্ন আকারের নির্দিষ্ট করে এবং উল্লেখ না করে ইনপুট বাফারিং সম্পর্কে স্পষ্ট পেতে পারেন (কারণ এটি অগ্রাধিকার নেয়)bs=

উদাহরণস্বরূপ, যদি আপনি এটি করেন:

IN| dd ibs=1| OUT

... তারপর একটি POSIX ddহবে write()দ্বারা 512 বাইটের অংশ সংগ্রহ প্রত্যেক একেলা read()একটি একক আউটপুট ব্লক মধ্যে বাইট।

অন্যথায়, যদি আপনি ...

IN| dd obs=1kx1k| OUT

... একটি POSIX ddহবে read() সর্বাধিক একটি সময়ে 512 বাইট, কিন্তু write()প্রত্যেক মেগাবাইট আকারের আউটপুট ব্লক (কার্নেল যার ফলে এবং সম্ভবত গত ছাড়া - কারণ যে ফাইলের শেষে থাকবে) মধ্যে ইনপুট সংগ্রহ করে পূর্ণ পূর্ণ আকারের আউটপুট ব্লক

এছাড়াও স্পেক থেকে, যদিও:

  • count=n
    • শুধুমাত্র এন ইনপুট ব্লক অনুলিপি করুন।

count=i?bs=ব্লকগুলিতে মানচিত্রগুলি , এবং count=বহনযোগ্যভাবে একটি স্বেচ্ছাসেবী সীমা পরিচালনা করার জন্য আপনার দু'টি দরকার dd। দু'টি দিয়ে এটি করার সবচেয়ে কার্যকরী উপায় ddহ'ল একটির আউটপুটটিকে অন্যের ইনপুটটিতে পাইপ করা, যা অবশ্যই আমাদের মূল ইনপুট প্রকার নির্বিশেষে একটি বিশেষ ফাইল পড়ার / লেখার ক্ষেত্রের মধ্যে ফেলে দেয় ।

একটি আইপিসি পাইপ এর অর্থ [io]bs=দাঁড়ায় যে যখন আরোগুলি নির্দিষ্ট করে থাকে , নিরাপদে এটি করার জন্য আপনাকে অবশ্যই এই মানগুলি সিস্টেমের নির্ধারিত PIPE_BUFসীমাতে রাখতে হবে । পসিএক্স জানিয়েছে যে সিস্টেমের কার্নেলটি কেবলমাত্র নির্ধারিত সীমার মধ্যেই পারমাণবিক read()write()এর গ্যারান্টি দিতে হবে । POSIX গ্যারান্টী বা নিশ্চয়তা হতে কমপক্ষে ...PIPE_BUFlimits.hPIPE_BUF

  • {_POSIX_PIPE_BUF}
    • পাইপে লেখার সময় সর্বাধিক সংখ্যক বাইট যা পরমাণু হওয়ার নিশ্চয়তা রয়েছে।
    • মান: 512

... (এটি ডিফল্ট ddআই / ও ব্লকসাইজ হিসাবেও ঘটে ) তবে আসল মানটি সাধারণত কমপক্ষে 4 কে হয়। একটি আপ-টু-ডেট লিনাক্স সিস্টেমে এটি ডিফল্টরূপে k৪ কে।

সুতরাং আপনি যখন আপনার ddপ্রক্রিয়াগুলি সেট আপ করবেন তখন আপনাকে তিনটি মানের উপর ভিত্তি করে একটি ব্লক ফ্যাক্টরের উপর এটি করা উচিত :

  1. বিএস = (obs = 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 তথ্য অনুলিপি করার জন্য নিরাপদ করতে পারে (আংশিক পড়া বা লেখার কারণে দুর্নীতির ঝুঁকি নেই) এমনকি count=যেকোনও পসিক্স সিস্টেমে নির্বিচারে ইনপুট ডব্লু / ডাব্লু / কোনও স্বেচ্ছাসেবিত ইনপুট টাইপ করার সময় এবং একক বাইট না হারিয়ে when

এখানে পসিক্স স্পেকের একটি স্নিপেট রয়েছে :

  • ibs=expr
    • বাইপগুলিতে ইনপুট ব্লকের আকার নির্দিষ্ট করুন (ডিফল্ট 512)expr
  • obs=expr
    • বাই দ্বারা আউটপুট ব্লকের আকার নির্দিষ্ট করুন (ডিফল্ট 512)expr
  • bs=expr
    • উভয় ইনপুট এবং আউটপুট ব্লক মাপগুলি exprবাইট, সুপারসিডিং ibs=এবং এ সেট করুন obs=। কোন রূপান্তর ছাড়া অন্য তাহলে sync, noerrorএবং notruncউল্লেখ করা হয়, প্রতিটি ইনপুট ব্লক সংক্ষিপ্ত ব্লক সমষ্টি ছাড়া একটি একক ব্লক হিসাবে আউটপুট অনুলিপি করা হবে।

আপনি এর আরও কিছু এখানে আরও ভালভাবে ব্যাখ্যা করতে পারেন ।


5

সকেট, পাইপ, বা টিটিসের সাহায্যে () পড়ুন এবং লিখুন () অনুরোধ করা আকারের চেয়ে কম স্থানান্তর করতে পারে, সুতরাং এগুলিতে ডিডি ব্যবহার করার সময় আপনার পুরো ব্লক পতাকাটি প্রয়োজন need তবে নিয়মিত ফাইল এবং ব্লক ডিভাইসগুলির সাথে, কেবলমাত্র দু'বার সময় যখন তারা সংক্ষিপ্ত পঠন / লেখার কাজ করতে পারে: আপনি যখন ইওএফ পৌঁছান, বা যদি কোনও ত্রুটি হয়। এই কারণেই ফুলব্লক পতাকা ব্যতীত ডিডি-র পুরানো প্রয়োগগুলি ডিস্ক সদৃশতার জন্য ব্যবহারে নিরাপদ ছিল।


সব আধুনিক ইউনিয়নের ক্ষেত্রেই কি এটি সত্য? (আমি জানি এটি কোনও সময়ে লিনাক্সের ক্ষেত্রে সত্য ছিল না, সম্ভবত ২.০.x বা ২.২.x অবধি ছিল। আমি mke2fsনিঃশব্দে ব্যর্থ হয়েছি বলে মনে করি কারণ এটি write()কিছু নন-পাওয়ার -২-আকারের (3 কেবি আইআইআরসি) এবং কার্নেলটি বৃত্তাকার দিয়েছিল) ২ এর পাওয়ারে নেমে যান)
গিলস

সম্পূর্ণরূপে একটি ভিন্ন ইস্যু মনে হচ্ছে @ গিলস। আপনাকে সর্বদা ব্লক ডিভাইস সহ সঠিক ব্লক আকারের একাধিক ব্যবহার করতে হবে। আমি নিশ্চিত যে এটি সমস্ত নীতিমালার ক্ষেত্রে সত্য, এবং এটি উইন্ডোজের ক্ষেত্রেও সত্য।
psusi

টেপগুলি ছাড়াও কোনও ডিভাইসের ব্লক আকার খালি কার্নেলটির যত্ন নেওয়া বা না করা বিশুদ্ধরূপে। cat </dev/sda >/dev/sdbএকটি ডিস্ক ক্লোন ঠিক কাজ করে।
গিলস

@ গিলস যেহেতু বিড়াল উপযুক্ত ব্লকের আকার ব্যবহার করে, যেমন অর্বউভার তার উত্তরে উল্লেখ করেছে।
psusi

না, কোনও "উপযুক্ত ব্লকের আকার" নেই। catপারফরম্যান্সের জন্য বাফার আকারটি বেছে নেয়; এটি কার্নেল থেকে কোনও ডিভাইস সম্পর্কিত তথ্য পায় না। টেপগুলি ছাড়াও, আপনি যে কোনও আকারের ব্লক ডিভাইসে read()এবং করতে পারেন write()। লিনাক্সে কমপক্ষে, st_blksizeকেবলমাত্র সেই ফাইল সিস্টেমের উপর নির্ভর করে যেখানে ব্লক ডিভাইস ইনোডটি অন্তর্নিহিত ডিভাইসে নয়।
গিলস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.