টি করতে পাইপ দেওয়ার সময় স্টাডাউটের লাইন-বাফারিং জোর করুন


117

সাধারণত, stdoutলাইন-বাফার হয়। অন্য কথায়, যতক্ষণ আপনারprintf যুক্তিটি একটি নতুন লাইন দিয়ে শেষ হয়, আপনি লাইনটি তাত্ক্ষণিকভাবে মুদ্রণের জন্য আশা করতে পারেন। পুনর্নির্দেশের জন্য পাইপ ব্যবহার করার সময় এটি ধরা পড়ে নাtee

আমার কাছে একটি সি ++ প্রোগ্রাম রয়েছে a, যা সর্বদা, স্ট্রিংগুলি আউটপুট করে\n -terminated, এর stdout

যখন এটি নিজেই চালিত হয় ( ./a), প্রত্যাশার মতো সবকিছু সঠিকভাবে এবং সঠিক সময়ে প্রিন্ট করে। তবে, যদি আমি এটিতে পাইপ tee(./a | tee output.txt ) এটি প্রস্থান না করা অবধি কিছু মুদ্রণ করে না, যা ব্যবহারের উদ্দেশ্যকে পরাস্ত করে tee

আমি জানি যে আমি fflush(stdout)সি ++ প্রোগ্রামে প্রতিটি মুদ্রণ অপারেশনের পরে একটি যুক্ত করে এটি ঠিক করতে পারতাম । তবে কি কোনও ক্লিনার, সহজ উপায় আছে? আমি কি চালাতে পারি এমন কোনও কমান্ড রয়েছে, উদাহরণস্বরূপ, এটি stdoutপাইপ ব্যবহার করার পরেও লাইন-বাফার হতে বাধ্য করবে ?

উত্তর:


67

প্যাকেজের unbufferঅংশ যা চেষ্টা করুন expect। আপনার সিস্টেমে এটি ইতিমধ্যে থাকতে পারে।

আপনার ক্ষেত্রে আপনি এটি ব্যবহার করুন:

./a | unbuffer -p tee output.txt

( -pপাইপলাইন মোডের জন্য যেখানে আনবুফার স্টিডিন থেকে পড়ে এবং বাকি আর্গুমেন্টে কমান্ডে দেয়)


ধন্যবাদ, এটি কাজ করেছে, যদিও আমাকে ওএস এক্স-এ ডিফল্টরূপে অন্তর্ভুক্ত বলে মনে হচ্ছে না বলে expectনিজেকে সংকলন unbufferকরতে হয়েছিল।
হুবিসফট

@ হুবিসফট: আপনার পক্ষে এটি কাজ করে আমি আনন্দিত। unbufferশুধুমাত্র একটি ছোট স্ক্রিপ্ট তাই আপনার পুরো প্যাকেজটি পুনরায় সংকলনের প্রয়োজন হবে না।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

হ্যাঁ, সম্ভবত না, কিন্তু ./configure && make10 সেকেন্ড সম্পর্কে নেন এবং তারপর আমি শুধু সরানো unbufferথেকে /usr/local/bin:)
houbysoft

3
আমি এটি ম্যাক (10.8.5) এর মাধ্যমে ব্রিউয়ের মাধ্যমে ইনস্টল করেছি: ব্রিউ ইনস্টল প্রত্যাশা - উইথ-ব্রিউড-টি-কে
নিলস

2
এফডাব্লুআইডাব্লু, কারণ আনবুফার কিছুটা বিভ্রান্তিকর, প্রাসঙ্গিক কাঠামোটি unbuffer {commands with pipes/tee}
ভুয়া নাম

127

আপনি চেষ্টা করতে পারেন stdbuf

$ stdbuf -o 0 ./a | tee output.txt

(বড়) ম্যান পৃষ্ঠার অংশ:

  -i, --input=MODE   adjust standard input stream buffering
  -o, --output=MODE  adjust standard output stream buffering
  -e, --error=MODE   adjust standard error stream buffering

If MODE is 'L' the corresponding stream will be line buffered.
This option is invalid with standard input.

If MODE is '0' the corresponding stream will be unbuffered.

Otherwise MODE is a number which may be followed by one of the following:
KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.
In this case the corresponding stream will be fully buffered with the buffer
size set to MODE bytes.

এটি মনে রাখবেন, যদিও:

NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does
for e.g.) then that will override corresponding settings changed by 'stdbuf'.
Also some filters (like 'dd' and 'cat' etc.) dont use streams for I/O,
and are thus unaffected by 'stdbuf' settings.

আপনি ব্যবহার না করা stdbufউপর tee, আপনি এটি চালাচ্ছেন a, তাই এই আপনাকে প্রভাবিত করা উচিত নয়, যদি না আপনি এর বাফারিং সেট a's স্ট্রিম aগুলি উৎস'।

এছাড়াও, stdbufহয় না POSIX কিন্তু গনুহ-coreutils অংশ।


3
ধন্যবাদ, তবে এটি ওএস এক্স-তে উপলব্ধ বলে মনে হচ্ছে না (প্রশ্নটি ট্যাগটি অক্স-সিংহ)।
হুবিসফট

2
@ হুবিসফট - আমি নিশ্চিত যে জিএনইউ সরঞ্জামগুলি ওএস এক্সে ইনস্টল করা যেতে পারে
জর্ডানম

1
@ জর্ডানম: সম্ভবত, তবে পুরো জিএনইউ সরঞ্জামগুলি ইনস্টল করার জন্য
এটির

1
এই উত্তরটি আপভোটড হয়েছে কারণ stdbufইতিমধ্যে আমরা ব্যবহার করা সেন্টো লিনাক্স বিতরণগুলিতে উপলব্ধ এবং unbufferতা নেই। ধন্যবাদ!
হু ওয়াল্টারস

6
পাইথন স্ক্রিপ্টের জন্য স্টডিবিফ কাজ করবে না, তবে আপনি -uপাইথনের পক্ষে বাফারিং অক্ষম করতে পারেন :python3 -u a.py | tee output.txt
হনজা

27

আপনি কমান্ডটি ব্যবহার করে সিউডো-টার্মিনালে আপনার কমান্ডটি কার্যকর করার চেষ্টা করতে পারেন script(যা পাইপে লাইন-বাফার আউটপুট প্রয়োগ করতে পারে)!

script -q /dev/null ./a | tee output.txt     # Mac OS X, FreeBSD
script -c "./a" /dev/null | tee output.txt   # Linux

সচেতন হন scriptকমান্ডটি মোড়ানো কমান্ডের প্রস্থান স্থিতি আবার প্রচার করে না।


3
script -t 1 /path/to/outputfile.txt ./aআমার ব্যবহারের ক্ষেত্রে দুর্দান্ত কাজ করেছে। এটি outputfile.txtআপনার শেলের স্টাডাউটে মুদ্রণের সময় সমস্ত আউটপুট লাইভ করে । ব্যবহার করার দরকার নেইtee
পিটার বার্গ

26

আপনি stdio.h থেকে setlinebuf ব্যবহার করতে পারেন।

setlinebuf(stdout);

এর মাধ্যমে বাফারিংটি "লাইন বাফার" করা উচিত।

আপনার যদি আরও নমনীয়তার প্রয়োজন হয় তবে আপনি সেটভুফ ব্যবহার করতে পারেন।


8
আমি ভাবছি কেন এই সমাধানটির এত কম ব্যয় হয়েছে। এটিই একমাত্র সমাধান যা কলারের উপরে বোঝা চাপিয়ে দেওয়া নয়।
অক্সিজেন

1
মনে রাখবেন যে এটি স্ট্যান্ডার্ড সি (বা এমনকি পসিক্স) নয়। এটি ব্যবহার করা সম্ভবত ভাল setvbuf(stdout, NULL, _IOLBF, 0), যা ঠিক সমান।
rvighne

এটি ওএস এক্স ক্যাটালিনায় আমার ইস্যুটিকে সি ++ প্রোগ্রাম দিয়ে স্থির করেছিল যা প্রিন্টফ () ছিল এবং আমি টি করতে পাইপ দিচ্ছিলাম তবে প্রোগ্রামটি শেষ হয়ে গেলে কেবল আউটপুটটি দেখছিলাম।
jbaxter

2

আপনি যদি এর পরিবর্তে সি ++ প্রবাহ শ্রেণীর ব্যবহার করেন, তাহলে প্রত্যেক std::endl হয় একটি অন্তর্নিহিত ফ্লাশ। সি-স্টাইলের মুদ্রণ ব্যবহার করে, আমি মনে করি যে আপনি প্রস্তাবিত পদ্ধতিটি ( fflush()) একমাত্র উপায়।


4
দুর্ভাগ্যক্রমে, এটি সত্য নয়। আপনি st + :: endl বা std :: ফ্লাশ ব্যবহার করার পরেও c ++ std :: cout এর সাথে একই আচরণটি পর্যবেক্ষণ করতে পারেন। বাফারিং শীর্ষে ঘটে এবং লিনাক্সের সবচেয়ে সহজ সমাধানটি সেটলাইন বুফ বলে মনে হয় (স্টাডআউট); যখন আপনি প্রোগ্রামটির লেখক এবং উত্স কোড পরিবর্তন করতে সক্ষম না হয়ে উপরের অন্যান্য সমাধানগুলি ব্যবহার করে তখন মূল () এর প্রথম প্রথম লাইন হিসাবে।
অক্সিজেন

1
@ অক্সিজেন এটি সত্য নয়। আমি এটি চেষ্টা করেছিলাম এবং টি-তে পাইপিং করার সময় এন্ডেল বাফারটি ফ্লাশ করে (প্রিন্টফের মতো নয়)। কোড: #include <iostream> #include <unistd.h> int main(void) { std::cout << "1" << std::endl; sleep(1); std::cout << "2" << std::endl; }। এখানে বর্ণিত হিসাবে অ্যান্ডল সর্বদা বাফারকে ফ্লাশ করে: en.cppreferences.com/w/cpp/io/manip/endl
কার্টিস ইয়ালাপ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.