मैच खोजने के बाद बाहर निकलने के लिए ग्रीप धीमा?


20

मैं एक बैश स्क्रिप्ट लिखने की कोशिश कर रहा हूं जो डिवाइस कनेक्शन के लिए btmon को पोल करता है। मुझे एक काम करने वाला समाधान मिल गया है, लेकिन यह बेतुका धीमा है, और ऐसा लगता है कि मुद्दा एक मैच (लगभग 25 सेकंड) खोजने के बाद बाहर निकलने के लिए बहुत धीमा है। मैं grepइसे पूरी तरह से तेज करने या इसके उपयोग से बचने के लिए क्या कर सकता हूं ?

#!/bin/bash
COUNTER=0
while :
  do
    until btmon | grep -m 1 '@ Device Connected'
      do :
    done
    let COUNTER=COUNTER+1
    echo on 0 | cec-client RPI -s -d 1
    sleep 5
    echo as | cec-client RPI -s -d 1
    until btmon | grep -m 1 '@ Device Disconnected'
      do :
    done
    let COUNTER=COUNTER-1
    if [ $COUNTER -eq 0 ];
      then echo standby 0 | cec-client RPI -s -d 1;
    fi
done

संपादित करें: स्पष्ट करने के लिए, btmonऔर ब्लूज़ सूट का एक ब्लूटूथ निगरानी उपकरण है, और cec-client एक उपयोगिता है जिसे HDMI-CEC सीरियल बस (अन्य चीजों के बीच) में आदेश जारी करने के लिए libCEC के साथ पैक किया गया है।


2
btmonआउटपुट कितना "सामान" करता है? क्या आप सुनिश्चित हैं कि यह केवल बफरिंग का मामला नहीं है?
स्टीलड्राइवर

@steeldriver सेकेंड। क्या आपने पाइप में बफरिंग को अक्षम करने की कोशिश की है ?
l0b0

btmon प्रति सेकंड लगभग 250 अक्षरों को आउटपुट करता है।
रोब

@ l0b0 मैंने unbuffer कमांड के साथ बफरिंग को अक्षम करने की कोशिश की, लेकिन ऐसा लगता है कि grep को बिल्कुल भी बाहर निकलने से रोकना चाहिए? मैंने grep से --line- बफर मोड के लिए मजबूर करने की कोशिश की, लेकिन वह मदद नहीं करता था।
रोब

यह हो सकता है कि btmonस्वयं बफिंग लागू हो, जिस स्थिति में आप भाग्य से बाहर हैं।
l0b0

जवाबों:


28

में:

cmd1 | cmd2

अधिकांश गोले (बॉर्न शेल, (t) csh, साथ ही यश और AT & T ksh के कुछ संस्करणों में कुछ शर्तों के तहत उल्लेखनीय अपवाद हैं) दोनों का इंतजार करते हैं cmd1और cmd2

में bash, आप नोटिस करेंगे

sleep 1 | uname

एक सेकंड के बाद लौटता है।

में:

btmon | grep -m 1 '@ Device Disconnected'

grepजैसे ही यह पैटर्न की एक घटना मिली है, से बाहर निकल जाएगा, लेकिन bashअभी भी इंतजार करेगा btmon

btmonआम तौर पर अगली बार पाइप पर लिखने के बाद किसी SIGPIPE की मृत्यु हो जाएगी grep, लेकिन अगर वह फिर कभी कुछ नहीं लिखता है, तो उसे वह संकेत कभी नहीं मिलेगा।

आप के #! /bin/bashसाथ प्रतिस्थापित कर सकते हैं #! /bin/ksh93कि एक खोल के साथ संगत है bashऔर एक है कि केवल एक पाइपलाइन के अंतिम घटक के लिए इंतजार कर रहा है। फिर

btmon | grep -m 1 '@ Device Disconnected'

grepरिटर्न के बाद , btmonपृष्ठभूमि में चलना छोड़ दिया जाएगा और शेल बाकी स्क्रिप्ट के साथ जारी रहेगा।

यदि आप रिटर्न के btmonरूप में जल्द से जल्द मारना चाहते थे grep, तो POSIXly, आप कुछ ऐसा कर सकते थे:

sh -c 'echo "$$"; exec btmon' | (
   read pid
   grep -m1 '@ Device Disconnected' || exit
   kill "$pid" 2> /dev/null
   true)

3
यह समझाने के लिए धन्यवाद कि यह ऐसा क्यों कर रहा है। यह मेरे लिए नहीं था कि बैश btmon के बाहर निकलने की प्रतीक्षा कर रहा हो। Ksh93 को स्वैप करना खूबसूरती से काम करता है!
रोब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.