EOP পর্যন্ত বিড়ালের মাধ্যমে পাইপ দেওয়া না থাকলে গ্রেপ আউটপুট দেয় না


19

এই ন্যূনতম উদাহরণ দেওয়া

( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; )

আউটপুট LINE 1এবং তারপর, এক সেকেন্ড পর আউটপুট LINE 2, যেমন প্রত্যাশিত


আমরা যদি এই পাইপ grep LINE

( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) | grep LINE

আচরণটি পূর্বের ক্ষেত্রে যেমন প্রত্যাশিত তেমনই একই রকম ।


যদি বিকল্পভাবে হয় তবে আমরা এটিতে পাইপ দিই cat

( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) | cat

আচরণটি আবার প্রত্যাশার মতো একই ।


তবে আমরা যদি পাইপ করি grep LINEএবং তারপরে cat,

( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) | grep LINE | cat

এক সেকেন্ড পাস না হওয়া পর্যন্ত কোনও আউটপুট নেই এবং উভয় লাইন অবিলম্বে আউটপুটে উপস্থিত হবে যা আমি আশা করি না


কেন এটি হচ্ছে এবং আমি প্রথম সংস্করণটিকে প্রথম তিনটি আদেশের মতো আচরণ করার জন্য কীভাবে তৈরি করতে পারি?


catফাইলগুলি সংযুক্ত করে। আপনি পাইপ দিয়ে কি করতে চেষ্টা করছেন cat?
ডগলাস

15
@ ডগলাসহেল্ড যখন যুক্তি ছাড়াই ডাকা হয় তখন catকেবল পড়ে stdinএবং আউটপুট প্রবেশ করে stdout। অবশ্যই, আমি এই প্রশ্নের জটিল কাপড় অনেক সঙ্গে স্থানে এসে echoএবং cat, কিন্তু এই, নিষ্কাশিত আপ অনেক সহজ উদাহরণ সঙ্গে সমস্যা শো থেকে অপ্রাসঙ্গিক যাবে।
লিসিয়াস

3
@ ডগলাসহেল্ড: বিড়ালকে পাইপ দেওয়া প্রায়শই স্টাডাউটকে টার্মিনাল না হওয়ার জন্য বাধ্য করে। উদাহরণস্বরূপ, রঙিন আউটপুট ব্যবহার না করার জন্য অনেক কমান্ড পাওয়ার এটি একটি সহজ উপায়।
wchargin

আমি শপথ করছি এটি স্ট্যাক ওভারফ্লোতে অন্য প্রশ্নের নকল !
iBug

@ ওচার্জিন আপনাকে অনেক ধন্যবাদ, আপনি আমাকে পোস্টিক্স সম্পর্কে নতুন কিছু শিখিয়েছেন যা আমি কখনই জানতাম না।
ডগলাস

উত্তর:


38

যখন (কমপক্ষে জিএনইউ) grepআউটপুটটি টার্মিনাল নয়, তখন এটি তার আউটপুটটিকে বাফার করে, যার ফলে আপনি যে আচরণটি দেখছেন তার কারণ হয়। আপনি এই গনুহ যেকোন একটি ব্যবহার করে নিষ্ক্রিয় করতে পারেন grepএর --line-bufferedবিকল্প:

( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) | grep --line-buffered LINE | cat

বা stdbufইউটিলিটি:

( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) | stdbuf -oL grep LINE | cat

পাইপে বাফারিং বন্ধ করুন এই বিষয়টিতে আরও রয়েছে।


26

সরল ব্যাখ্যা

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

আরও বিস্তারিত ব্যাখ্যা

এটি সুপরিচিত, তবে কিছুটা ভুল, ব্যাখ্যা। আসলে, স্ট্যান্ডার্ড আউটপুট লাইনের বাফার নয় তবে জিএনইউ সি লাইব্রেরি এবং বিএসডি সি লাইব্রেরিতে স্মার্ট বাফার করেছে। স্ট্যান্ডার্ড আউটপুট এছাড়াও যখন মান পড়া রাঙা ইনপুট নিঃশেষিত তার ইন-মেমোরি বাফার (প্রাক পঠিত ইনপুটের) এবং C লাইব্রেরি ডাকতে হয়েছে read()আরো কিছু ইনপুট আনতে এবং এটি একটি নতুন লাইনের শুরুতে পড়া হয়। (এর এক কারণ হ'ল অচলাবস্থা রোধ করা যখন অন্য কোনও প্রোগ্রাম নিজেকে ফিল্টারের উভয় প্রান্তের সাথে সংযুক্ত করে এবং ফিল্টারটিতে লেখার মাধ্যমে এবং এটি থেকে পড়াতে পর্যায়ক্রমে লাইন বাই লাইন পরিচালনা করতে সক্ষম হতে পারে; জিএনইউতে "কোপ্রোসেসিস" এর মতো) awkউদাহরণ স্বরূপ.)

সি লাইব্রেরির প্রভাব

grepএবং অন্যান্য ইউটিলিটিগুলি এটি করে - বা আরও কঠোরভাবে, তারা যে সি লাইব্রেরিগুলি ব্যবহার করে এটি এটি করে কারণ এটি তাদের সি স্ট্যান্ডার্ড আউটপুটটি কী কী তা আবিষ্কার করে তার উপর ভিত্তি করে সি ভাষায় প্রোগ্রামিংয়ের একটি সংজ্ঞায়িত বৈশিষ্ট্য। যদি (এবং কেবলমাত্র) এটি কোনও ইন্টারেক্টিভ ডিভাইস না হয় তবে তারা পূর্ণ বাফারিং বেছে নেয়, অন্যথায় তারা স্মার্ট বাফারিং বেছে নেয়। একটি পাইপ একটি ইন্টারেক্টিভ ডিভাইস হিসাবে বিবেচিত হয় না, কারণ কমপক্ষে ইউনিক্স এবং লিনাক্স বিশ্বে ইন্টারেক্টিভ ডিভাইস হওয়ার সংজ্ঞাটি মূলত isatty()প্রাসঙ্গিক ফাইল বর্ণনাকারীর জন্য কলকে সত্য বলে প্রত্যাবর্তন করে।

পূর্ণ বাফারিং অক্ষম করার জন্য কার্যবিধির কাজ

কিছু ইউটিলিটি যেমন grepআইডিসিঙ্ক্র্যাটিক বিকল্প রয়েছে যেমন --line-bufferedএই সিদ্ধান্ত পরিবর্তন করে, যা আপনি দেখতে পাচ্ছেন ভুল-নাম দেওয়া হয়েছে। তবে ফিল্টার প্রোগ্রামগুলির একটি অদৃশ্যভাবে ছোট ছোট ভগ্নাংশের যে আসলে ব্যবহার করতে পারে such

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

আরও পড়া


1
যদি "লাইন বাফারড" শব্দটি কোনও ভুলবিত্ত হয় তবে তা আসলে ভুল grepনয়, তবে অন্তর্নিহিত লাইব্রেরি কলগুলির, setbuf/ এরsetvbuf । আমি সি স্ট্যান্ডার্ডের জন্য একটি নির্ভরযোগ্য অনলাইন রেফারেন্স সম্পর্কে জানি না, তবে লিনাক্স এবং ফ্রিবিএসডি ম্যান পৃষ্ঠাগুলি সহ পসিক্সের বর্ণনাকে setvbuf"লাইনের বাফার" বলে call এমনকি এটি জন্য প্রতীকী ধ্রুবক _IOLBF
ilkkachu

ভাল এখন আপনি আরও ভাল শিখেছি। বাফারিং কৌশল হয় GNU C লাইব্রেরি doco বর্ণিত, সংক্ষেপে যদ্যপি। বিষয়টি নিয়ে লরেন্ট বেরকোট আরও সুস্পষ্ট। আমি এটিও উল্লেখ করেছি।
জেডিবিপি

আউটপুট বাফারিংয়ের এই দুর্দান্ত ব্যাখ্যার জন্য আমি "আপনার প্রত্যাশা ভুল" বলে মনে করি না। আমি আশা করি আপনি আপত্তি করবেন না যে আমি এটি সরিয়ে দিয়েছি এবং উত্তরের প্রতিটি বিভাগের জন্য কিছু বর্ণনামূলক শিরোনাম যুক্ত করেছি।
অ্যান্টনি জি - মনিকার পক্ষে ন্যায়বিচার

2
@ ইলক্কাচু সি স্ট্যান্ডার্ডটি আসলে "লাইন বাফারড" ব্যবহার করে। 7.21.3 প্রতি ফাইল , অনুচ্ছেদ 3 : "যখন একটি স্ট্রিম আনফার করা হয় না ... ... যখন একটি স্ট্রিম পুরোপুরি বাফার হয় ... ... যখন একটি স্ট্রিমটি লাইন বার্ফার করা হয় তখন অক্ষরগুলি হোস্ট পরিবেশে বা হিসাবে একটি হিসাবে সংক্রমণিত হওয়ার উদ্দেশ্যে হয় যখন কোনও নতুন-লাইন চরিত্রের মুখোমুখি হয় তখন অবরুদ্ধ করুন ... ... "প্রকৃতপক্ষে, সি স্ট্যান্ডার্ডটি পাঁচবার" লাইনের বাফারড "শব্দটি ব্যবহার করে। সুতরাং এটি কোনও মিসনোমার নয়।
অ্যান্ড্রু হেনেল

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

7

ব্যবহার

grep --line-buffered

গ্রেপ একবারে একাধিক লাইন বাফার না করতে।

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