क्या मैं tr के लिए बफरिंग अक्षम कर सकता हूँ


10

trलगता है कि इसके इनपुट को बफ़र करना है ताकि यह कमांड LongRunningCommand|tr \\n ,केवल उत्पादन शुरू कर दे, जब लॉन्ग रंजिश से कुछ किलोबाइट इनपुट के बाद जमा हो जाए।

क्या trइस बफरिंग या किसी अन्य कमांड को रोकने के लिए बाध्य करने का कोई तरीका है जो बफरिंग के बिना किसी अन्य चरित्र के साथ नई लाइनों को बदल सकता है?


PS मैंने पहले ही दो सुझावों को सफलता के बिना पाइप में बफरिंग बंद करने की कोशिश की है ।


1
क्या आपने stdbufLongRunningCommand या tr, या दोनों को अलग-अलग तरीके से लागू किया?
मयूह

इस तरह दोनों के लिए:stdbuf -o0 fping -aAq -r2 -g 10.30.0.1 10.30.0.255 2>/dev/null | stdbuf -i0 tr \\n ,
ndemou

fping -q"प्रति-जांच परिणाम नहीं दिखाते हैं, लेकिन केवल अंतिम सारांश" दिखाते हैं, इसलिए शायद यह केवल एक लंबे अंत में लिखता है?
meuh

कोई भी फ़ैपिंग कमांड अपने आप ठीक काम नहीं करता है। हालांकि सुझाव के लिए बहुत धन्यवाद
ndemou

2
मुझे लगता है कि बफरिंग की समस्या वास्तव में आउटपुट में है tr। कोशिश करें|stdbuf -i0 -o0 tr ...
meuh

जवाबों:


12

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

इसके लिए एक उल्लेखनीय अपवाद है mawkजो read()इनपुट बफ़र के पूर्ण होने तक फिर से चालू रहेगा।

एप्लिकेशन हालांकि उनके आउटपुट (स्टडआउट) को बफर करते हैं । सामान्य व्यवहार यह है कि यदि आउटपुट टेंट में जा रहा है, तो बफरिंग लाइन-वार होगी (अर्थात, यह तब तक लिखना बंद नहीं करेगी, जब तक कि आउटपुट के लिए पूरी लाइन न हो, या बहुत के लिए ब्लॉक-फुल हो। लंबी लाइन), जबकि हर दूसरे प्रकार की फ़ाइल के लिए, बफ़रिंग ब्लॉक के द्वारा होती है (अर्थात, यह तब तक लिखना शुरू नहीं करेगा जब तक कि लिखने के लिए एक ब्लॉक पूरा न हो जाए (4KiB / 8KiB जैसा कुछ ... सॉफ्टवेयर और सिस्टम पर निर्भर करता है) ))।

तो आपके मामले में LongRunningCommandसंभवतया ब्लॉक द्वारा इसका आउटपुट बफ़र्स करता है (क्योंकि इसका आउटपुट एक पाइप है और एक tty नहीं है), और trसंभावना है कि इसका आउटपुट लाइन से इसका आउटपुट बफ़र्स करता है क्योंकि इसका आउटपुट शायद टर्मिनल है।

लेकिन, चूँकि आप प्रत्येक न्यूलाइन वर्ण को उसके आउटपुट से हटाते हैं, यह कभी भी एक लाइन को आउटपुट नहीं करेगा, इसलिए बफरिंग ब्लॉक से होगी।

तो यहाँ आप दोनों के लिए बफ़रिंग अक्षम करना चाहते हैं LongRunningCommandऔर tr। GNU या FreeBSD सिस्टम पर:

stdbuf -o0 LongRunningCommand | stdbuf -o0 tr '\n' ,

ध्यान दें कि यदि आप कॉमा के साथ लाइनों में शामिल होना चाहते हैं, तो बेहतर दृष्टिकोण का उपयोग करना है paste -sd , -। इस तरह आउटपुट को एक नए वर्ण द्वारा समाप्त कर दिया जाएगा (आपको शायद अभी भी बफरिंग को अक्षम करना होगा)।


@mikeserv। हाँ, और एक है कि stdio बफरिंग का उपयोग करता है और setvbuf / setbuffer कॉल नहीं करता है ... अपने आप से और एक शेल चिन नहीं है। लेकिन आम तौर पर जीएनयू और फ्रीबीएसडी सिस्टम पर, वे सभी शर्तें पूरी होती हैं।
स्टीफन चेज़लस

ओह। मैंने केवल यह सीखा कि कुछ दिन पहले जब मैं निराश था कि मैं अपने संकलित संकलन के लिए i / o धाराओं को प्रभावित नहीं कर सकता था sed। खेद है अगर यह कष्टप्रद था - लेकिन मुझे नहीं पता था कि यह सामान्य ज्ञान था। मुझे लगता है कि यह LD_PRELOAD का उपयोग करता है।
15

Stéphane क्या होता है की पूरी तरह से स्पष्टीकरण के लिए धन्यवाद। बहुत सराहना की
ndemou

5

के साथ newlines को बदलने के लिए ",", आप चला सकते हैं

awk '{ printf "%s,", $0 }'

GNU अवेक ( gawk) और सोलारिस nawkस्टड पर लाइन बफ़रिंग के साथ चलेंगे और जब टर्मिनल के लिए आउटपुट होगा तो कोई बफरिंग स्टडआउट नहीं होगा। यदि आपका awk है mawk, जो Ubuntu पर होता है, तो आप इसे -W interactiveउसी बफ़रिंग व्यवहार को प्राप्त करने का विकल्प दे सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.