"वॉच" कमांड का आउटपुट जब तक एक विशेष स्ट्रिंग का अवलोकन नहीं किया जाता है और तब तक बाहर निकल जाता है


29

मैं प्रोग्राम के आउटपुट को देखने के लिए एक रास्ता खोज रहा हूं जब तक कि किसी विशेष स्ट्रिंग को नहीं देखा जाता है और तब बाहर निकलता है। यह इस प्रश्न से बहुत मिलता-जुलता है , लेकिन मैं एक फाइल को पूंछने के बजाय एक कमांड को 'टेल' करना चाहता हूं।

कुछ इस तरह:

watch -n1 my_cmd | grep -m 1 "स्ट्रिंग इम लुकिंग फॉर"

(लेकिन यह मेरे लिए काम नहीं करता है।)

अद्यतन: मुझे यह स्पष्ट करने की आवश्यकता है कि 'my_cmd' लगातार आउटपुट टेक्स्ट नहीं करता है, लेकिन स्ट्रिंग के पाए जाने तक बार-बार कॉल करने की आवश्यकता होती है (यही वजह है कि मैंने 'वॉच' कमांड के बारे में सोचा)। इस संबंध में, 'my_cmd' कई अन्य यूनिक्स कमांड्स की तरह है: ps, ls, lsof, last, आदि।


मुझे लगता है कि यह tail -fएक प्रोग्राम आउटपुट के साथ-साथ एक फ़ाइल के लिए संभव था ... क्या मैं गलत हूं?
जोआनिस

@Joanis। आप सही हैं, लेकिन मेरे मामले में 'my_cmd' लगातार आउटपुट नहीं देता है और बार-बार कॉल किया जाना चाहिए (अधिकांश कमांड जैसे: ps, ls, lsof, आदि)
gdw2

जवाबों:


41

एक लूप का उपयोग करें:

until my_cmd | grep -m 1 "String Im Looking For"; do : ; done

इसके बजाय :, आप sleep 1सीपीयू को कम करने के लिए (या 0.2) का उपयोग कर सकते हैं ।

लूप तब तक चलता है जब तक कि grep कमांड के आउटपुट में स्ट्रिंग नहीं पाता। -m 1इसका मतलब है "एक मैच काफी है", अर्थात पहला मैच खोजने के बाद grep खोजना बंद कर देता है।

आप grep -qपहले मैच को ढूंढने के बाद भी उपयोग कर सकते हैं , लेकिन मिलान रेखा को प्रिंट किए बिना।


इस आदेश की एक व्याख्या की सराहना की जाएगी।
मार्क डब्ल्यू

@MarkW: अपडेट किया गया।
चोरोबा

किसी और ने उल्लेख किया है grep -qजो एक और विकल्प है। स्ट्रिंग खोजने के बाद grep क्विट करता है।
सूर्य

ध्यान दें कि यह कमांड बार-बार कमांड को प्रश्न में चलाएगा, जो वांछनीय हो सकता है या नहीं।
एड्रियन

1
@A__: यह वांछनीय है, जैसा कि ओपी में "अपडेट" के तहत कहा गया है।
चोरोबा

11
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
  • ! कमांड पाइप लाइन के निकास कोड को हटा देता है
  • grep -m 1 स्ट्रिंग मिलने पर बाहर निकलता है
  • watch -e यदि कोई त्रुटि हुई है, तो रिटर्न

लेकिन यह वास्तव में उस मिलान रेखा को प्रदर्शित करने के लिए बेहतर हो सकता है, जिसे अब तक फेंक दिया गया है।


विस्तृत विवरण के लिए धन्यवाद, लेकिन यह मेरे लिए काम नहीं करता है। मेरे watchआदेश (CentOS) में -eध्वज नहीं है (जो वास्तव में मायने नहीं रखना चाहिए)। इससे भी महत्वपूर्ण बात, हालांकि, जब स्ट्रिंग पाया जाता है, तो घड़ी चलती रहती है और बाहर नहीं निकलती है। ऐसा लगता है कि जब grep -mबाहर निकलता है, तो यह केवल मारता है my_cmd, लेकिन नहीं watch
gdw2

नहीं, कोई फर्क नहीं पड़ता !, "-ई" ध्वज घड़ी को छोड़ने के लिए है जब कमांड में त्रुटि कोड 0. से भिन्न होता है क्योंकि इसकी वर्तमान घड़ी आपके प्लेटफॉर्म पर जारी नहीं रहती है। किसी भी तरह, जानने के लिए अच्छा, मेरे Ubuntu 11.10 स्थापना पर सब कुछ ठीक है। मुझे कभी-कभी मैक ओएसएक्स के साथ बहुत पुरानी कमांडलाइन टूल के बारे में भी परेशानी होती है और मैं मैक पोर्ट का उपयोग कर रहा हूं ताकि अधिक वर्तमान सॉफ्टवेयर प्राप्त कर सकें।
गणित

यदि पैटर्न मिलता है तो यह बंद हो जाता है, लेकिन ऐसा तब तक कोई आउटपुट नहीं दिखाता है जब तक
मार्क

आप इसके लिए काम कर सकते हैं tee, लेकिन यह एक भ्रामक न्यूलाइन प्रस्तुत करता है, मुझे नहीं पता कि अभी कैसे watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
गणित

हाँ, यह मेरे लिए काम नहीं किया। watchजब स्ट्रिंग मिलती है, तो कर्तव्यपरायणता से देखना बंद कर देता है, लेकिन जब तक आप एक कुंजी दबाते हैं तब तक यह वास्तव में बाहर नहीं निकलता है। बहुत करीब।
18:18

8

उन लोगों के लिए, जिनके पास लगातार लिखने के लिए एक कार्यक्रम है, आपको केवल 'सिंगल मैच' विकल्प के साथ इसे संक्षिप्त करना है। एक बार grep मिलान स्ट्रिंग को खोज लेता है, तो यह बाहर निकल जाएगा, जो उस प्रक्रिया पर स्टडआउट को बंद कर देता है जिसे grep पर पाइप किया जा रहा है। इस घटना को चाहिए स्वाभाविक रूप से कार्यक्रम शान से बाहर निकलने के लिए कारण इतने लंबे समय के रूप में इस प्रक्रिया को फिर से लिखते हैं

क्या होगा कि यह प्रक्रिया SIGPIPE को प्राप्त होगी जब यह grep से बाहर निकलने के बाद बंद स्टडआउट को लिखने की कोशिश करता है। यहाँ पिंग के साथ एक उदाहरण है, जो अन्यथा अनिश्चित काल तक चलेगा:

$ ping superuser.com | grep -m 1 "icmp_seq"

यह आदेश पहले सफल 'पोंग' से मेल खाएगा, और फिर अगली बार बाहर निकलने की pingकोशिश करता है कि लेखन को रोकना है।


तथापि,

यह हमेशा गारंटी नहीं है कि प्रक्रिया फिर से रोकना लिख ​​देगी और इसलिए SIGPIPE को उठाया नहीं जा सकता है (उदाहरण के लिए, किसी लॉग फ़ाइल को पूंछते समय ऐसा हो सकता है)। इस परिदृश्य के लिए जो सबसे अच्छा समाधान मैंने तैयार किया है, उसमें फ़ाइल में लिखना शामिल है; कृपया टिप्पणी करें यदि आपको लगता है कि आप सुधार कर सकते हैं:

$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }

इसे तोड़ना:

  1. tail -f log_file & echo $! > pid- एक फ़ाइल पूंछता है, पृष्ठभूमि के लिए प्रक्रिया संलग्न करता है, और $!एक फ़ाइल के लिए पीआईडी ​​( ) बचाता है । मैंने इसके बजाय PID को एक चर में निर्यात करने की कोशिश की, लेकिन ऐसा लगता है कि यहां और जब PID का फिर से उपयोग किया जाता है, तो एक दौड़ की स्थिति होती है।
  2. { ... ;}- इन आदेशों को एक साथ समूहित करें ताकि हम वर्तमान संदर्भ को बनाए रखते हुए grep में आउटपुट कर सकें (चर को बचाने और पुन: उपयोग करने में मदद करता है, लेकिन उस हिस्से को काम करने में सक्षम नहीं किया गया)
  3. | - पाइप लेफ्ट साइड के स्टडआउट से राइट साइड के स्टड पर
  4. grep -m1 "find_me" - लक्ष्य स्ट्रिंग ढूंढें
  5. && kill -9 $(cat pid)- बल मार (SIGKILL) tailप्रक्रिया के grep बाहर निकलने के बाद एक बार मिलान स्ट्रिंग को ढूंढता है
  6. && rm pid - हमारे द्वारा बनाई गई फ़ाइल को हटा दें

0
my_cmd | tail +1f | sed '/String Im Looking For/q'

यदि सिंटैक्स का tailसमर्थन नहीं करता है +1f, तो प्रयास करें tail -f -n +1। ( -n +1इसे शुरुआत में शुरू करने के लिए कहता है; tail -fडिफ़ॉल्ट रूप से आउटपुट के अंतिम 10 लाइनों के साथ शुरू होता है।)


कृपया प्रश्न के लिए मेरा अपडेट देखें।
gdw2

0

अपने प्रोग्राम कॉल के परिणाम को फ़ाइल में जोड़ें। फिर tail -fवह फाइल। इस तरह से यह काम करना चाहिए ... मुझे उम्मीद है।

जब आप उस प्रोग्राम को कॉल करना शुरू करते हैं, तो आपको फ़ाइल को मिटाना होगा या इसके लिए कुछ अस्पष्टता को जोड़ना होगा, ताकि यह तुरंत फिर से मेल न खाए जो आप देख रहे थे।

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