> & -> / দেব / নাল থেকে আরও দক্ষ?


58

গতকাল আমি এই এসও মন্তব্যটি পড়েছি যা বলে যে শেলটিতে (কমপক্ষে bash) >&-"এর মতো একই ফলাফল রয়েছে" >/dev/null

সেই মন্তব্যটি আসলে এবিএস নির্দেশকে তার তথ্যের উত্স হিসাবে উল্লেখ করে । তবে সেই উত্সটি বলে যে >&-সিনট্যাক্সটি "ফাইলের বর্ণনাকারীদের বন্ধ করে"।

কোনও ফাইল বিবরণকারী বন্ধ করে নাল ডিভাইসে পুনর্নির্দেশ করার দুটি ক্রিয়া সম্পূর্ণ সমতুল্য কিনা তা আমার কাছে পরিষ্কার নয়। সুতরাং আমার প্রশ্ন: তারা হয়?

এটির উপরিভাগে মনে হয় যে কোনও ডেস্ক্রিপ্টর বন্ধ করা একটি দরজা বন্ধ করার মতো তবে এটি একটি শূন্য ডিভাইসে পুনর্নির্দেশ করা লম্বোর দরজা খোলার মতো! দু'টি আমার কাছে একরকম মনে হয় না কারণ যদি আমি একটি বন্ধ দরজা দেখি তবে আমি এর বাইরে কিছু ফেলে দেওয়ার চেষ্টা করব না, তবে যদি আমি একটি খোলা দরজা দেখি তবে আমি ধরে নিতে পারি আমি পারব।

অন্য কথায়, আমি সর্বদা ভাবছিলাম যে এর >/dev/nullঅর্থ যদি cat mybigfile >/dev/nullআসলে ফাইলটির প্রতিটি বাইট প্রক্রিয়া করে এবং এটি /dev/nullভুলে যায় তবে তা লিখতে পারে। অন্যদিকে, যদি শেলটি একটি বন্ধ ফাইল বর্ণনাকারীর মুখোমুখি হয় তবে আমি ভাবতে চাই (তবে নিশ্চিত নই) এটি কেবল কিছু লিখবে না যদিও প্রশ্নটি catএখনও প্রতিটি বাইট পড়বে কিনা remains

এই মন্তব্যটি বলে >&-এবং >/dev/null" হওয়া উচিত " একই রকম, তবে এটি আমার কাছে এত উত্তম উত্তর নয়। আমি স্ট্যান্ডার্ড বা উত্স কোর সম্পর্কে কিছু উল্লেখ সহ আরও অনুমোদনমূলক উত্তর পেতে চাই ...


আমি যদি দাতব্য হতে চাই, তবে আমি বলব যে মন্তব্যের অর্থ এই নয় যে সেগুলি একইভাবে বাস্তবায়িত করা হয়েছিল, কেবলমাত্র যে উভয়ের উভয়েরই একই ফলস্বরূপ আপনাকে প্রোগ্রামটির আউটপুটটি দেখতে বাধা দেওয়ার ফলাফল রয়েছে।
বারমার

উত্তর:


71

না, আপনি অবশ্যই 0, 1 এবং 2 ফাইল বর্ণনাকারী বন্ধ করতে চান না

আপনি যদি এটি করেন, অ্যাপ্লিকেশনটি প্রথমবার কোনও ফাইল খুলবে, এটি স্টিডিন / স্টাডাউট / স্টার্ডার হয়ে যাবে ...

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

echo text | tee file >&-

যখন tee(কমপক্ষে কিছু বাস্তবায়ন, যেমন ব্যস্তবক্স ') লেখার জন্য ফাইলটি খুলবে, তখন এটি ফাইল বিবরণী ১ (স্টাডআউট) এ খোলা থাকবে। সুতরাং এখানে দুটি বার teeলিখতে হবে :textfile

$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "text\n", 8193)                 = 5
write(1, "text\n", 5)                   = 5
write(1, "text\n", 5)                   = 5
read(0, "", 8193)                       = 0
exit_group(0)                           = ?

এটি সুরক্ষা দুর্বলতার কারণ হিসাবে পরিচিত। এই ক্ষেত্রে:

chsh 2>&-

এবং chsh(একটি নির্ধারিত অ্যাপ্লিকেশন) এর মধ্যে ত্রুটি বার্তা লেখার শেষ হতে পারে /etc/passwd

কিছু সরঞ্জাম এবং এমনকি কিছু গ্রন্থাগারও এর বিরুদ্ধে রক্ষা করার চেষ্টা করে। উদাহরণস্বরূপ, জিএনইউ teeলেখার জন্য খোলার ফাইলগুলি 0, 1, 2 বরাদ্দ করা হয় তবে ব্যস্তবক্স teeনা করে ফাইল বর্ণনাকারীটিকে 2 এর উপরে একটিতে স্থানান্তরিত করবে।

বেশিরভাগ সরঞ্জাম, যদি তারা স্টাডাউটে লিখতে না পারে (কারণ এটি খোলা নেই), স্ট্যাডারে একটি ত্রুটি বার্তার প্রতিবেদন করবে (ব্যবহারকারীর ভাষায় যার অর্থ স্থানীয়করণের ফাইলগুলি খোলার এবং পার্স করার জন্য অতিরিক্ত প্রক্রিয়াজাতকরণ ...), সুতরাং এটি উল্লেখযোগ্যভাবে কম দক্ষ হবে এবং সম্ভবত প্রোগ্রামটি ব্যর্থ হওয়ার কারণ হবে।

যে কোনও ক্ষেত্রে, এটি আরও কার্যকর হবে না। প্রোগ্রামটি এখনও একটি write()সিস্টেম কল করবে। এটি কেবল তখনই কার্যকর হতে পারে যদি প্রোগ্রামটি প্রথম ব্যর্থ write()সিস্টেম কলের পরে স্টাডাউট / স্ট্ডারকে লেখা ছেড়ে দেয় তবে প্রোগ্রামগুলি সাধারণত এটি করে না। তারা হয় সাধারণত একটি ত্রুটি নিয়ে প্রস্থান করে বা চেষ্টা চালিয়ে যায়।


4
আমি মনে করি চূড়ান্ত অনুচ্ছেদটি শীর্ষে থাকলে এই উত্তরটি আরও ভাল হতে পারে (যেহেতু এটিই সরাসরি ওপি-র প্রশ্নের উত্তর দেয়) এবং পরে এটি বেশিরভাগ কাজ না করলেও কেন এটি একটি খারাপ ধারণা তা নিয়ে আলোচনা শুরু করে। তবে আমি এটি নিতে হবে, একটি upvote আছে। ;)
একটি সিভিএন

@ স্টাফেনচাজেলাস: মাইকেল যেমন বলেছিলেন, আমি শেষের প্যারাটি আশা করেছি, তবে এটি স্পষ্ট করে দেওয়ার জন্য ধন্যবাদ সম্ভবত সম্ভবত সমস্যা তৈরি করে। সুতরাং আমি অনুমান করি একটি আনুষঙ্গিক প্রশ্ন হবে, কখন এফডি বন্ধ করা কার্যকর হবে? নাকি আমার আলাদা প্রশ্ন হিসাবে জিজ্ঞাসা করা উচিত?
জামাদগনি


1
@ জামাদগনি যদি স্টাফেনের প্রদত্ত লিঙ্কটি প্রশ্নের উত্তর না দেয় তবে আমি বলব যে এটি দুটি পদ্ধতির আপেক্ষিক দক্ষতার সাথে সরাসরি সম্পর্কিত না হওয়ায় একটি পৃথক প্রশ্নের সূচনা বলে মনে হচ্ছে।
একটি সিভিএন

1
আমি প্রশংসা করি যে স্টিফেন এই প্রস্থের গুরুত্বপূর্ণ সুরক্ষা সতর্কতা দিয়ে শুরু করেছিলেন, কারণ শেষ অনুচ্ছেদটি উপরে থাকলে এটি কম দৃশ্যমান হবে। আমার কাছ থেকে +1
অলিভিয়ার দুলাক 18

14

আইওডাব্লু আমি সবসময় ভাবছিলাম যে এর >/dev/nullঅর্থ cat mybigfile >/dev/nullআসলে ফাইলটির প্রতিটি বাইট প্রক্রিয়া করবে এবং এটি কী /dev/nullভুলে যায় তা লিখবে ।

এটি আপনার প্রশ্নের পুরো উত্তর নয়, তবে হ্যাঁ, এটি কীভাবে কাজ করে তা উপরেরটি।

catনামকৃত ফাইল (গুলি) বা কোনও ফাইলের নাম না থাকলে স্ট্যান্ডার্ড ইনপুট পড়ে এবং শেষের নামযুক্ত ফাইলের (স্ট্যান্ডার্ড ইনপুট সহ) কোনও ইওএফ-এর মুখোমুখি না হওয়া পর্যন্ত তার স্ট্যান্ডার্ড আউটপুটটিকে আউটপুট দেয়। এটি তার কাজ।

যোগ করে >/dev/nullআপনি স্ট্যান্ডার্ড আউটপুটটিকে / dev / নাল এ পুনঃনির্দেশ করছেন। এটি একটি বিশেষ ফাইল (একটি ডিভাইস নোড) যা এতে লিখিত কিছু ফেলে দেয় (এবং তাত্ক্ষণিক ইওএফটি পড়ার সময় ফেরত দেয়)। নোট করুন যে I / O পুনর্নির্দেশটি শেল দ্বারা প্রদত্ত একটি বৈশিষ্ট্য, প্রতিটি স্বতন্ত্র অ্যাপ্লিকেশন দ্বারা নয় এবং নাম / দেব / নাল সম্পর্কে যাদুকর কিছুই নেই , কেবলমাত্র ইউনিক্স-এর মতো সিস্টেমে সেখানে কী ঘটে ।

এটি লক্ষণীয়ও গুরুত্বপূর্ণ যে ডিভাইস নোডগুলির নির্দিষ্ট মেকানিকগুলি অপারেটিং সিস্টেম থেকে অপারেটিং সিস্টেমের মধ্যে পরিবর্তিত হয়, তবে বিড়াল (যা একটি জিএনইউ সিস্টেমে বোঝায়, কোর্টিলস) ক্রস প্ল্যাটফর্ম (একই উত্স কোডটি কমপক্ষে লিনাক্সে চালানো দরকার এবং বাধা) এবং তাই নির্দিষ্ট অপারেটিং সিস্টেমের কার্নেলগুলির উপর নির্ভরতা নিতে পারে না। অতিরিক্তভাবে, আপনি যদি অন্য কোনও নামের সাথে একটি / ডিভ / নাল এলিফ তৈরি করেন (লিনাক্সে, এর অর্থ একটি বড় / গৌণ ডিভাইস নম্বরযুক্ত একটি ডিভাইস নোড) তবে এটি এখনও কাজ করে works এবং সবসময় কার্যকরভাবে একই আচরণ করে বলে অন্য কোথাও লেখার ক্ষেত্রে রয়েছে (বলুন, / দেব / শূন্য)।

এটি অনুসরণ করে যে cat/ dev / নাল এর বিশেষ বৈশিষ্ট্যগুলি সম্পর্কে অজানা, এবং সম্ভবত প্রথম স্থানে পুনর্নির্দেশ সম্পর্কে অজানা, তবে এটি এখনও একই কাজ সম্পাদন করা দরকার: এটি নামক ফাইলগুলি পড়ে এবং এর সামগ্রীগুলি আউটপুট করে it / যারা ফাইল (গুলি) তার মান আউটপুট। শূন্যে যাওয়ার জন্য স্ট্যান্ডার্ড আউটপুট catহ'ল এটি catনিজেই উদ্বিগ্ন নয় ।


2
আপনার উত্তরটি প্রসারিত করতে: হ্যাঁ, প্রতিটি বাইট মেমোরিতে পড়তে বাধ্য cat mybigfile > /dev/nullকরবে । এবং, প্রতিটি বাইটের জন্য, এটি কল করবে । প্রোগ্রামটি সম্পর্কে অজানা, theশ্বর একেবারে কিছুই করবেন না (সম্ভবত কিছু তুচ্ছ বইয়ের বাদে)। লিখতে প্রতিটি বাইট প্রক্রিয়াজাতকরণের প্রয়োজন হয় না। catbigfilenwrite(1, buffer, n)catwrite/dev/null
জি ম্যান

2
আমার মনে আছে আমি যখন / dev / নাল ডিভাইসের লিনাক্স কার্নেল উত্সটি পড়ি তখন আমার উড়ে যাওয়া হয়েছিল। আমি প্রত্যাশা করছিলাম ফ্রি () ইনগ বাফার ইত্যাদির কিছু বিস্তৃত ব্যবস্থা থাকবে তবে, না, এটি মূলত একটি রিটার্ন ()।
ব্রায়ান মিন্টন

4
@ জি-ম্যান: আমি জানি না যে আপনি সব ক্ষেত্রেই এটির সত্যতা নিশ্চিত করতে পারেন। আমি প্রমাণ এখন খুঁজে পাচ্ছি না, কিন্তু আমি পারেন কিছু বাস্তবায়ন প্রত্যাহার catবা cpযে কাজ করবে mmapমেমরিতে সোর্স ফাইল বড় খন্ডে ing, তারপর কলিং write()ম্যাপ অঞ্চলের উপর। আপনি যদি লিখতে থাকেন /dev/null, write()উত্স ফাইলের পৃষ্ঠাগুলিতে কোনও ত্রুটি ছাড়াই কলটি একবারে ফিরে আসবে, সুতরাং এটি কখনই ডিস্ক থেকে পড়তে পারা যায় না।
নাট এল্ডারেজ

2
এছাড়াও, জিএনইউর মতো কিছু catঅনেক প্ল্যাটফর্মগুলিতে চালিত হয় তবে উত্স কোডটিতে একটি নৈমিত্তিক নজরে প্রচুর পরিমাণে প্রদর্শিত হবে #ifdef: এটি আক্ষরিকভাবে একই কোড নয় যা সমস্ত প্ল্যাটফর্মগুলিতে সঞ্চালিত হয় এবং প্রচুর সিস্টেম-নির্ভর বিভাগ রয়েছে।
নাট এল্ডারেজ

@ নেটএলড্রেডজ: মজার বিষয়, তবে আমি কেবল মাইকেল এর উত্তরের উপর ভিত্তি করেই যাচ্ছিলাম, আপনি মাইকেলকে যেভাবে বিরোধিতা করছেন তা আপনি আমার সাথে এতটা বিরোধিতা করছেন না।
জি ম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.