트랩 및 Unix 신호를 사용하여 셸에서 키 입력 읽기

트랩 및 Unix 신호를 사용하여 셸에서 키 입력 읽기

아래 코드 조각의 목적 trap과 다중 호출을 이해할 수 없습니다.stty

누군가 나에게 무슨 일이 일어나고 있는지 간략하게 설명해줄 수 있기를 바랍니다.

getkey() {
  local stty="$(stty -g)"
  trap "stty $stty; trap SIGINT; return 128" SIGINT
  stty cbreak -echo 
  local key
  while true; do
    key=$(dd count=1 2>/dev/null) || return $?
    if [ -z "$1" ] || [[ "$key" == [$1] ]]; then
      break
    fi
  done
  stty $stty
  echo "$key"
  return 0
}

답변1

local stty="$(stty -g)"

현재 터미널 설정을 저장합니다. stty $stty, 함수가 정상적으로 반환될 때 실행되고 SIGINT는 이러한 설정을 복원합니다.

trap "stty $stty; trap SIGINT; return 128" SIGINT

기능이 SIGINT( Ctrl+를 눌러 전송된 신호 C)에 의해 중단되면 터미널 설정이 복원되고 128이 반환됩니다. (왜 128인가요? 궁금합니다. 일반적으로 시그널의 종료 상태는 128 + 시그널 번호입니다.)

stty cbreak -echo 

터미널의 대략적인 편집 기능(문자/단어/줄 삭제)을 비활성화하고 문자를 입력할 때 에코를 끕니다.

  key=$(dd count=1 2>/dev/null) || return $?

터미널에서 최대 512바이트를 읽습니다( count는 블록 수, 기본 블록 크기는 512바이트입니다). 좀 이상합니다. 목적이 바이트를 읽는 것이라고 생각했습니다. dd최소한 1바이트가 사용 가능해지면 즉시 반환되므로 사용자가 입력하는 경우 실제로 단일 바이트를 반환하지만 프로그램이 키 입력을 입력하거나 시스템이 느린 경우 더 많은 바이트를 읽을 수 있습니다 . 이 코드의 장점은 사용자가 멀티바이트 문자를 입력하는 경우 루프 반복에서 해당 문자를 구성하는 모든 바이트를 읽을 수 있다는 것입니다(그러나 보장되지는 않습니다).

0이 아닌 상태가 반환 되면 dd이는 읽기 오류 또는 신호가 즉시 반환됨을 나타냅니다. 터미널 설정이 복원되지 않습니다. 이는 오류입니다. 대부분의 경우 오류는 사용자가 Ctrl+ 를 누르는 C경우(이 경우 터미널 설정이 복원됨)이거나 터미널이 사라지는 경우(이 경우 요점은 논쟁의 여지가 있음)입니다.

  if [ -z "$1" ] || [[ "$key" == [$1] ]]; then
    break
  fi

읽은 바이트가 함수 인수의 문자 중 하나이면 루프를 종료합니다. 인수가 비어 있으면 모든 문자가 루프를 종료합니다. 매개변수는 정확히 문자 목록이 아니며 다음 위치에 있습니다.와일드카드문자 세트 구문: 초기 ^또는 역방향 세트, 대부분의 위치에 있는 빼기 기호는 !범위(예: 0-9) 로 구문 분석 [:…:]되고 각각 문자 클래스 및 조합 기호를 나타냅니다. 백슬래시는 다음 또는 을 [.….]참조합니다 .\[]-

관련 정보