निम्नलिखित शेल कमांड से इनपुट स्ट्रीम की केवल विषम रेखाओं के प्रिंट की उम्मीद थी:
echo -e "aaa\nbbb\nccc\nddd\n" | (while true; do head -n 1; head -n 1 >/dev/null; done)
लेकिन इसके बजाय यह सिर्फ पहली पंक्ति प्रिंट करता है aaa
:।
जब इसका उपयोग -c
( --bytes
) विकल्प के साथ किया जाता है तो वही नहीं होता है:
echo 12345678901234567890 | (while true; do head -c 5; head -c 5 >/dev/null; done)
यह कमांड 1234512345
उम्मीद के मुताबिक आउटपुट करता है। लेकिन यह केवल उपयोगिता के कोर्यूटिल्स कार्यान्वयन में काम करता है head
। बिजीबॉक्स कार्यान्वयन अभी भी, अतिरिक्त वर्ण खाती है तो उत्पादन सिर्फ है 12345
।
मुझे लगता है कि कार्यान्वयन का यह विशिष्ट तरीका अनुकूलन उद्देश्यों के लिए किया जाता है। आप नहीं जान सकते कि रेखा कहाँ समाप्त होती है, इसलिए आपको नहीं पता कि आपको कितने वर्णों को पढ़ने की आवश्यकता है। इनपुट स्ट्रीम से अतिरिक्त वर्णों का उपभोग नहीं करने का एकमात्र तरीका स्ट्रीम बाईट को पढ़ना है। लेकिन एक बार में एक बाइट स्ट्रीम से पढ़ना धीमा हो सकता है। इसलिए मुझे लगता head
है कि इनपुट स्ट्रीम को एक बड़े पर्याप्त बफर में पढ़ता है और फिर उस बफर में लाइनों को गिनता है।
जब --bytes
विकल्प का उपयोग किया जाता है तो केस के लिए भी ऐसा नहीं कहा जा सकता है। इस मामले में आप जानते हैं कि आपको कितने बाइट्स पढ़ने हैं। तो आप इस बाइट की संख्या को ठीक से पढ़ सकते हैं और इससे अधिक नहीं। Corelibs कार्यान्वयन इस अवसर का उपयोग करता है, लेकिन बिजीबॉक्स एक नहीं, यह अभी भी अधिक बाइट की तुलना में एक बफर में आवश्यक पढ़ता है। यह संभवतः कार्यान्वयन को सरल बनाने के लिए किया जाता है।
तो सवाल। क्या head
उपयोगिता के लिए इनपुट स्ट्रीम से अधिक पात्रों का उपभोग करना सही है, जितना कि पूछा गया था? क्या यूनिक्स उपयोगिताओं के लिए किसी प्रकार का मानक है? और अगर वहाँ है, तो क्या यह व्यवहार निर्दिष्ट करता है?
पुनश्च
आपको Ctrl+C
ऊपर दिए गए कमांड्स को रोकने के लिए प्रेस करना होगा। यूनिक्स उपयोगिताओं से परे पढ़ने पर विफल नहीं होते हैं EOF
। यदि आप प्रेस नहीं करना चाहते हैं, तो आप अधिक जटिल कमांड का उपयोग कर सकते हैं:
echo 12345678901234567890 | (while true; do head -c 5; head -c 5 | [ `wc -c` -eq 0 ] && break >/dev/null; done)
जो मैंने सादगी के लिए उपयोग नहीं किया।