읽지 않을 때 쉘 스크립트 루프가 발생함 [닫기]

읽지 않을 때 쉘 스크립트 루프가 발생함 [닫기]

터미널이 활성 창이 아닐 때 실행 중인 스크립트를 중지하기 위해 키보드 단축키를 사용하는 가장 좋은 방법을 찾으려고 노력 중입니다.

이를 통해 키보드 이벤트를 관찰하는 방법에 대한 아이디어를 얻을 수 있습니다 cat /dev/input/eventX(여기서 X는 키 입력 이벤트에 해당하는 숫자입니다).

evtest그런 다음 이벤트(키 입력)가 사람이 읽을 수 있는 형식으로 인쇄될 때까지 실행되는 도구에 대해 배웠습니다 .

지금까지 제가 관리해 온 스크립트인데 예상대로 작동하지 않습니다. 완벽한 솔루션에서는 사용자가 언제든지 Key_Space를 눌러 스크립트를 중지할 수 있지만 여기서는 불가능하다고 생각합니다. 그래서 내 해결책은 루프 시작 부분에 2초의 창을 제공하는 것이었습니다.

#!/bin/bash                                                              
exitCase='*type 1 (EV_KEY), code 57 (KEY_SPACE)*'

while [ true ]  do
    evtest  /dev/input/eventX |  read -s -t 2  line 
    if [ "$line" = "$exitCase" ] 
    then
        echo caught event
        exit 0

    else           
        echo loop doing stuff
    fi
done

문제는 스크립트가 반복 없이 한 번 실행된다는 것입니다. 이를 수행하는 더 좋은 방법이 있습니까? 아니면 종료 상황과 일치하는 입력이 나타날 때까지 스크립트를 반복하도록 어떻게 조정할 수 있습니까?

또 다른 잠재적인 문제는 한 번의 키 입력이 여러 줄을 인쇄한다는 것입니다. 그래서 하나가 필요할 수도 있습니다 evtest /dev/input/eventX | while read line. 하지만 시도해 본 후에는 이벤트를 기다리는 동안이 아니라 이벤트에서만 반복되도록 할 수 있습니다.

답변1

파이프의 오른쪽은 evtest | read line별도의 하위 셸에서 실행되므로(따라서 line유용한 항목을 설정하지 않으므로) 테스트에서안 돼요true이고 스크립트는 무기한 실행됩니다. 표시되지 않은 스크립트에 코드가 있을 수 있습니까?

read어쨌든 에서 시작할 필요는 없습니다 evtest. 대신 다음을 사용할 수 있습니다 grep(이렇게 하면 마지막에 언급한 "잠재적인 문제"도 해결됩니다).

#!/bin/sh

exitCase='*type 1 (EV_KEY), code 57 (KEY_SPACE)*'

while true; do
    if evtest /dev/input/eventX | grep -q -Fx -e "$exitCase"; then
        echo caught event
        break
    else           
        echo loop doing stuff
    fi
done

evtest정확히 동일한 행이 생성되면 루프가 중단됩니다 $exitCase. 조용히 하라고 -q지시하는 옵션(종료 상태에만 관심이 있음)에서 문자열을 다음과 결합해야 합니다 .grep-Fgrep$exitCase정규식이 아닌 -x전체 줄을 일치시켜야 합니다(문자열이 시작과 끝에 고정되어 있는 것처럼 하위 문자열 없이).

grep시간 초과를 적용 하려면 GNU coreutils를 evtest사용할 수 있습니다 timeout.

관련 정보