क्यों "पूंछ -f ... | पूंछ ”किसी भी उत्पादन का उत्पादन करने में विफल?


36

निम्न कमांड कोई आउटपुट क्यों नहीं देता है?

$ tail -f /etc/passwd | tail

बफरिंग के बारे में पढ़ने के बाद , मैंने कोई फायदा नहीं हुआ:

$ tail -f /etc/passwd | stdbuf -oL tail

ध्यान दें कि निम्नलिखित उत्पादन का उत्पादन करता है:

$ tail /etc/passwd | tail

तो यह करता है:

$ tail -f /etc/passwd | head

मैं पूंछ संस्करण 8.21 (GNU कोरुटिल्स) का उपयोग कर रहा हूं।


17
Last के अंतिम 10 अंक क्या हैं?
कीथ थॉम्पसन

जवाबों:


15

मुझे लगा कि मैंने UNIX में सब कुछ देखा है। इस सवाल ने मुझे मेरी तस्करी से दूर कर दिया। क्या शानदार सवाल है!

tailअंतिम एक्स लाइनें दिखाता है। tail -fवही करता है, लेकिन अनिवार्य रूप से एक अनंत लूप में: स्टार्ट-अप पर, फ़ाइल की अंतिम एक्स लाइनों को दिखाएं, फिर कुछ ओएस जादू (जैसे कि अशुद्धि करना) का उपयोग करके, मॉनिटर करें और नई लाइनें दिखाएं।

अपना काम tailकरने के लिए, फ़ाइल के अंत का पता लगाने में सक्षम होना चाहिए। यदि tailफ़ाइल का अंत नहीं मिल रहा है, तो यह अंतिम एक्स लाइनें नहीं दिखा सकता है, क्योंकि "अंतिम" अपरिभाषित है। तो tailइस मामले में क्या करता है? यह फ़ाइल के अंत का पता लगाने तक इंतजार करता है।

इस पर विचार करो:

$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f

यह कभी प्रगति नहीं करता है, क्योंकि फ़ाइल का कोई निश्चित अंत कभी नहीं होता है chatter

यदि आप tailआपको फ़ाइल सिस्टम पाइप से अंतिम पंक्तियाँ देने के लिए कहते हैं तो आपको वही व्यवहार मिलता है । विचार करें:

$ mkfifo test.pipe
$ tail test.pipe

stdbufकथित समस्या के आसपास पाने के लिए एक अच्छा प्रयास था। हालांकि मुख्य तथ्य यह है कि I / O बफरिंग मूल कारण नहीं है: एक निश्चित एंड-ऑफ-फ़ाइल की कमी है। यदि आप tail.c स्रोत कोड की जांच करते हैं , तो आप देखेंगे कि file_linesफ़ंक्शन टिप्पणी पढ़ता है:

END_POS EOF की फ़ाइल ऑफ़सेट (पिछले बाइट की ऑफ़सेट से बड़ी) है।

और यही जादू है। किसी भी कॉन्फ़िगरेशन में काम करने के लिए आपको पूंछ के लिए एक एंड-ऑफ-फ़ाइल की आवश्यकता होती है। headउस प्रतिबंध नहीं है, यह सिर्फ फ़ाइल की शुरुआत की जरूरत है (जो यह नहीं हो सकता है, कोशिश head test.pipe)। स्ट्रीम ओरिएंटेड टूल जैसे कि sedऔर awkन ही फाइल की शुरुआत या अंत की आवश्यकता है: वे बफ़र्स पर काम करते हैं।


37

tail -fकी पूंछ वास्तव में वर्तमान में कुछ अज्ञात है, इसलिए अगले tailको यह कैसे पता होना चाहिए । दूसरी ओर tail -fसिर कुछ पहले से ही ज्ञात है और वहाँ संसाधित किया जा सकता है।

या इसे सरल बनाने के लिए: tailफ़ाइल के अंत के सापेक्ष है, लेकिन tail -fकोई ईओएफ नहीं मिला (इसके समापन से पहले कम से कम नहीं) की आउटपुट स्ट्रीम ।

आप पहली बार मिल जाए tailकी पीआईडी और यह मार, आप चाहिए तो दूसरे से उत्पादन को देखते हैं।


21

तकनीकी जवाब

इनपुट के रूप में एक धारा के साथ चलने पर, tail एक nइनलाइन बफर को रखता है जो स्ट्रीम को पढ़ते समय भरता है, लेकिन यह स्ट्रीम के अंत तक पहुंचने तक उन लाइनों को आउटपुट नहीं कर सकता है, अर्थात यह EOFइनपुट से पढ़ने की कोशिश करते समय एक विशेष कोड प्राप्त करता है। स्ट्रीम। आह्वान tail -fबाहर नहीं निकलता है, इस प्रकार यह कभी भी अपनी धारा को बंद नहीं करेगा, जिससे उस धारा की 10 अंतिम पंक्तियों को वापस करना असंभव हो जाता है।


3

का कार्य tailइनपुट या फ़ाइल का अंतिम भाग - "पूंछ" दिखाना है। (विकल्प -fइस बारे में है कि यह बाद में क्या करता है, इसलिए यहां प्रासंगिक नहीं है।)

आइए एक फाइल के बारे में सोचते हैं:

किसी फ़ाइल का अंतिम भाग क्या है ?
मान लीजिए कि यह है किसी फ़ाइल अंतिम n लाइनें हैं

जब हम iइनपुट फाइल की लाइन पढ़ते हैं , तो यह कैसे तय करें कि उसे प्रिंट करने की आवश्यकता है या नहीं?
हम नहीं जानते कि यह अंतिम भाग में है - क्योंकि हम नहीं जानते कि अंतिम रेखा कौन सी होगी। सो हम् इसे अभी नहीं छाप सकते

हमें तब तक लाइन रखने की आवश्यकता है जब तक कि यह स्पष्ट न हो जाए कि यह आखिरी का हिस्सा हैn लाइनों , या अब इसका हिस्सा नहीं हो सकता है, क्योंकि हम इन nलाइनों को जानते हैं

यदि हम अब फाइल के अंत में आते हैं , तो हम जानते हैं कि nहमारे द्वारा रखी गई अंतिम लाइनें वास्तव में अंतिम हैंn में फाइल लाइनें हैं।

अब, के मामले में

tail -f /etc/passwd | tail

पहले tailफ़ाइल को पढ़ता है, और फिर उस से अधिक डेटा प्राप्त करने के लिए प्रतीक्षा करता है , वह भी लिखने के लिए। तो यह दूसरी पूंछ में फ़ाइल के अंत का संकेत नहीं देगा जब यह उस फ़ाइल के अंत में आता है जो इसे पढ़ता है। उसके बिना, दूसरी को फ़ाइल के अंत के tail बारे में सूचित नहीं किया जाता है , इसलिए यह कभी भी पता नहीं लगा सकता है कि अंतिम लाइनें कौन से हैं, इसे प्रिंट करना चाहिए।

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