스페이스바로 Bash 스크립트를 중지하는 방법은 무엇입니까?

스페이스바로 Bash 스크립트를 중지하는 방법은 무엇입니까?

저는 Bash로 작성된 Rubik's Cube 스톱워치를 작업 중이며 가능한 한 빨리 종료해야 할 때 Ctrl+를 사용할 수 없기 때문에 스페이스 바를 눌러 중지하고 싶습니다 .C

그럼 스페이스바만으로 프로그램을 멈출 수 있는 방법이 있을까요?

kill나는 알 수 없어서 명령을 올려다보았다 .

코드의 스톱워치 부분은 다음과 같습니다.

TMP0=$(date +%s%N)
while true; do
    TMP1=$(date +%s%N)
    DTMP=$(($TMP1-$TMP0))
    printf "\r$(($DTMP/1000000000)).${DTMP:(-9):2}"
done

답변1

Ctrl+를 누를 때 SIGINT를 전경 프로세스 그룹으로 보내는 것은 터미널입니다 c. 모든 캐릭터에 대해 이 작업을 수행하도록 구성할 수 있지만 스크립트가 종료되면 이전 설정을 복원하려고 합니다.

#!/bin/bash

settings="$(stty -g)"
trap 'stty "$settings"' EXIT
stty intr ' '

TMP0=$(date +%s%N)
while true; do
    TMP1=$(date +%s%N)
    DTMP=$(($TMP1-$TMP0))
    printf '\r%s' "$(($DTMP/1000000000)).${DTMP:(-9):2}"
done

settings="$(stty -g)"이전 설정을 저장합니다. stty intr ' '터미널이 + Space대신 에 반응하도록 만듭니다 . 스크립트가 종료되면 이전 설정을 복원하는 일을 담당합니다.Ctrlctrap 'stty "$settings"' EXIT

노트:

  • 트랩 코드에서는 stty $settingsstty "$settings". "의 예외입니다.항상 인용하다" 규칙. 인용은 단어 분할 및 파일 이름 생성(globbing)을 방지하지만 일부 구현에서는 stty단어 분할이 필요할 수 있으므로 변수를 인용하면 안 됩니다. 파일 이름 생성으로 인한 유해한 부작용을 방지하려면사양stty -g이 기능을 트리거하지 않는 문자열을 생성 해야 합니다 .

    편집하다:그것은 POSIX 사양의 결함이었습니다. 위의 코드가 수정되었습니다.

  • 문제가 발생하여 여전히 SIGINT를 생성하는 대화형 셸에 있는 경우 직접 Space호출해야 합니다 . stty intr ^C명령에 공백이 있지만 Ctrl+ 를 눌러 리터럴 공백 문자를 입력할 수 있다는 점을 기억하세요 v Space.

  • printf '\r%s' …나는 정적 형식과 동적 데이터가 printf귀하가 사용한 동적 형식보다 더 나은 "철학"에 적합하다고 생각하기 때문에 사용했습니다 .

" Space대신 Ctrl+ c"는 Space특별해지면 Ctrl+가 c더 이상 특별해지지 않음을 의미합니다. 당신은 그것을 결함이라고 부를 수도 있습니다.Ctrl사용자는 +가 c특별하게 유지되기를 기대합니다 .. 두 가지를 동시에 특별하게 만드는 것은 간단한 일이 아니지만 터미널 구성으로는 불가능하다고 생각합니다.

이 대체 버전은 거의 모든 키에서 중지되지만 Ctrl+는 c평소대로 작동합니다.

#!/bin/bash

while read -r -t 0.001; do :; done    # dump the buffer
TMP0=$(date +%s%N)
until read -r -n 1 -t 0.001; do
    TMP1=$(date +%s%N)
    DTMP=$(($TMP1-$TMP0))
    printf '\r%s' "$(($DTMP/1000000000)).${DTMP:(-9):2}"
done
echo

반응하게 하려면 Space읽은 내용을 확인해야 합니다.


until read -r -n 1 -t 0.001 && [ "$REPLY" = ' ' ]; do

Space이제 스크립트를 중지하는 메커니즘 은 Ctrl+가 c작동하는 방식과 매우 다릅니다.

답변2

스톱워치가 필요하지 않은 경우 어쨌든 결국 소요된 시간을 알고 싶다면 다음을 사용할 수 있습니다.

time read -r -n 1

다음과 같은 결과를 얻을 것입니다:

time read -r -n 1

real    1m30.909s
user    0m0.000s
sys     0m0.000s

거의 모든 키 입력으로 중지합니다(Kamil이 사용하는 방식과 유사 read).

또는 시간 부분만 원하는 경우:

{ time read -r -n 1; } 2>&1 | grep real | awk '{ print $2 }'

의 호의리치

관련 정보