tail
ब्लॉक नहीं करता है
हमेशा की तरह: हर चीज के लिए एक उत्तर होता है, जो छोटा, समझने में आसान, अनुसरण करने में आसान और पूरी तरह से गलत होता है। यहाँ tail -f /dev/null
इस श्रेणी में आता है;)
यदि आप इसे देखते हैं तो आप strace tail -f /dev/null
देखेंगे कि यह समाधान अवरुद्ध होने से दूर है! यह शायद sleep
प्रश्न में समाधान से भी बदतर है , क्योंकि यह inotify
सिस्टम जैसे अनमोल संसाधनों का उपयोग करता है। इसके अलावा अन्य प्रक्रियाएं जो लूप /dev/null
बनाने के लिए लिखती हैं tail
। (मेरे Ubuntu64 16.10 पर यह पहले से ही व्यस्त प्रणाली पर प्रति सेकंड कई 10 syscalls जोड़ता है।)
सवाल ब्लॉकिंग कमांड के लिए था
दुर्भाग्य से, ऐसी कोई बात नहीं है ..
पढ़ें: मुझे यह नहीं पता है कि इसे सीधे शेल के साथ संग्रहीत करें।
सब कुछ (यहां तक कि sleep infinity
) कुछ संकेत द्वारा बाधित हो सकता है। इसलिए यदि आप वास्तव में सुनिश्चित होना चाहते हैं तो यह असाधारण रूप से वापस नहीं आता है, यह एक लूप में चलना चाहिए, जैसे कि आपने पहले ही अपने लिए किया था sleep
। कृपया ध्यान दें, (लिनक्स पर) /bin/sleep
जाहिरा तौर पर 24 दिनों में छाया हुआ है (एक नज़र डालें strace sleep infinity
), इसलिए आप जो सबसे अच्छा कर सकते हैं वह यह है:
while :; do sleep 2073600; done
(ध्यान दें कि मेरा मानना है कि sleep
24 दिनों की तुलना में उच्च मूल्यों के लिए आंतरिक रूप से लूप होता है, लेकिन इसका मतलब है: यह अवरुद्ध नहीं है, यह धीरे-धीरे लूपिंग है। इसलिए इस लूप को बाहर क्यों नहीं ले जाएं?)
.. लेकिन आप एक अनाम के साथ काफी निकट आ सकते हैं fifo
आप कुछ बना सकते हैं जो वास्तव में तब तक ब्लॉक करता है जब तक कि कोई संकेत नहीं है प्रक्रिया को भेजें। निम्नलिखित उपयोग bash 4
, 2 पीआईडी और 1 fifo
:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
आप जाँच सकते हैं कि यह वास्तव में ब्लॉक के साथ strace
यदि आप चाहें:
strace -ff bash -c '..see above..'
इसका निर्माण कैसे हुआ
read
यदि कोई इनपुट डेटा नहीं है तो ब्लॉक करें (कुछ अन्य उत्तर देखें)। हालांकि, tty
(उर्फ stdin
) आमतौर पर एक अच्छा स्रोत नहीं है, क्योंकि जब उपयोगकर्ता लॉग आउट करता है तो यह बंद हो जाता है। इसके अलावा यह कुछ इनपुट चोरी कर सकता है tty
। अच्छा नहीं है।
read
ब्लॉक करने के लिए , हमें कुछ ऐसी चीज की प्रतीक्षा करने की आवश्यकता है fifo
जो कभी भी वापस नहीं आएगी। में bash 4
एक कमांड जो वास्तव में इस तरह के एक के साथ हमें प्रदान कर सकते है fifo
: coproc
। यदि हम ब्लॉकिंग का इंतजार करते हैं read
(जो कि हमारा है coproc
), तो हम कर रहे हैं। अफसोस की बात यह है कि खुले दो पीआईडी और ए रखने की जरूरत है fifo
।
एक नाम के साथ वेरिएंट fifo
यदि आप एक नाम का उपयोग करके परेशान नहीं करते हैं fifo
, तो आप इस प्रकार कर सकते हैं:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
पढ़ने पर लूप का उपयोग नहीं करना थोड़ा टेढ़ा है, लेकिन आप इसे fifo
जितनी बार चाहें उपयोग कर सकते हैं और read
एस टर्मैट का उपयोग कर सकते हैं touch "$HOME/.pause.fifo"
(यदि एक से अधिक बार प्रतीक्षा की जा रही है, तो सभी एक ही बार में समाप्त हो जाते हैं)।
या लिनक्स pause()
syscall का उपयोग करें
अनंत अवरोधन के लिए, एक लिनक्स कर्नेल कॉल है, जिसे कहा जाता है pause()
, जो हम चाहते हैं: हमेशा के लिए प्रतीक्षा करें (जब तक कोई संकेत नहीं आता)। हालाँकि इस (अभी तक) के लिए कोई उपयोगकर्ता कार्यक्रम नहीं है।
सी
ऐसा प्रोग्राम बनाना आसान है। यहां एक बहुत छोटा लिनक्स प्रोग्राम बनाने के लिए एक स्निपेट है जिसे pause
अनिश्चित काल के लिए रोक दिया जाता है (आवश्यकताएं diet
, gcc
आदि):
printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause
python
यदि आप स्वयं कुछ संकलन नहीं करना चाहते हैं, लेकिन आपने python
इंस्टॉल कर लिया है, तो आप लिनक्स के तहत इसका उपयोग कर सकते हैं:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(नोट: exec python -c ...
वर्तमान शेल को बदलने के लिए उपयोग करें , यह एक पीआईडी को मुक्त करता है। समाधान को कुछ आईओ पुनर्निर्देशन के साथ ही अप्रयुक्त एफडी से मुक्त किया जा सकता है। यह आपके ऊपर है।)
यह कैसे काम करता है (मुझे लगता है): ctypes.CDLL(None)
मानक सी लाइब्रेरी को लोड करता है और pause()
कुछ अतिरिक्त लूप के भीतर इसमें फ़ंक्शन चलाता है । सी संस्करण की तुलना में कम कुशल, लेकिन काम करता है।
आपके लिए मेरी सिफारिश:
लूपिंग स्लीप पर रहें। यह समझना बहुत आसान है, बहुत पोर्टेबल है, और अधिकांश समय ब्लॉक करता है।