경기를 찾은 후 Grep이 천천히 종료됩니까?


20

장치 연결을 위해 btmon을 폴링하는 bash 스크립트를 작성하려고합니다. 작동하는 솔루션을 가지고 있지만 터무니없이 느리며 일치하는 항목을 찾은 후 grep이 종료되는 데 매우 느린 것 같습니다 (약 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하고 Bluez 제품군의 일부인 블루투스 모니터링 도구이며 cec-client는 HDMI-CEC 직렬 버스를 통해 명령을 실행하기 위해 libCEC와 함께 패키지 된 유틸리티입니다.


2
얼마나 "물건"이 btmon출력됩니까? 버퍼링의 문제가 아니라고 확신하십니까?
steeldriver

@steeldriver Seconded. 파이프에서 버퍼링비활성화 하려고 했습니까 ?
l0b0

btmon은 초당 약 250자를 출력합니다.
Rob

@ l0b0 unbuffer 명령으로 버퍼링을 비활성화하려고 시도했지만 grep이 전혀 종료되지 않는 것 같습니다. 또한 grep을 --line-buffer 모드로 설정하려고 시도했지만 도움이되지 않는 것 같습니다.
Rob

btmon버퍼링 자체 를 구현할 수 있습니다 .이 경우 운이 좋지 않습니다.
l0b0

답변:


28

에서:

cmd1 | cmd2

대부분의 쉘 (Bourne 쉘 (t) CSH뿐만 아니라 YASH과 주목할만한 예외 인 어떤 조건에서 AT & T KSH의 일부 버전) 모두 대기 cmd1하고 cmd2.

에서 bash, 당신은 알 수 있습니다

sleep 1 | uname

1 초 후에 돌아갑니다.

에서:

btmon | grep -m 1 '@ Device Disconnected'

grep패턴이 한 번 발견되면 종료되지만 bash여전히 기다립니다 btmon.

btmon일반적으로 다음에 파이프 grep가 돌아온 후 파이프에 쓸 때 SIGPIPE로 죽지 만 다시는 아무것도 쓰지 않으면 해당 신호를 수신하지 않습니다.

당신은 대체 할 수 #! /bin/bash#! /bin/ksh93그가와 호환 쉘으로 bash만 파이프 라인의 마지막 구성 요소를 기다립니다 하나. 그런 다음

btmon | grep -m 1 '@ Device Disconnected'

grep반환 후 btmon백그라운드에서 실행 상태로 유지되고 쉘은 나머지 스크립트를 계속 수행합니다.

POSIXly 반납 btmon하자마자 죽이고 싶다면 grep다음과 같이 할 수 있습니다.

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

3
이것이 왜 그렇게 동작하는지 설명해 주셔서 감사합니다. bash가 btmon이 종료되기를 기다리는 것은 나에게 일어나지 않았습니다. ksh93으로 바꾸면 아름답게 작동합니다!
Rob
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.