완료 함수에서 /dev/tty 읽기

완료 함수에서 /dev/tty 읽기

다음 코드가 명령을 완료하지 못하는 이유는 무엇입니까 foo? 입력한 다음 를 입력하면 foo <Tab>쉘이 정지되고 누를 때까지 ^C(exit 명령이 완료됨) 어떤 입력도 허용되지 않습니다.

내 가정은 /dev/tty쉘이 그것을 읽었고 그것이 cat그것을 읽는 능력에 어떻게든 영향을 미친다는 것입니다. 그러나 이 경우에는 여전히 해결 방법이 필요합니다.

_foo() {
    _values 'foo' "$(cat < /dev/tty)"
}

compdef _foo foo

이 예는 의도적으로 단순화되었습니다. 실제 사용 사례는 가 아닌 터미널 인터페이스 프로그램(ncurses를 생각해 보세요)을 실행하는 것입니다 cat.

답변1

완료하는 동안 zsh 줄 편집기에 있으므로 다음을 실행한 것처럼 터미널 줄 규칙의 자체 줄 편집기가 비활성화됩니다.

stty -icanon -echo

이 모드에서는 입력 끝( 줄 규칙의 줄 편집기 동작의 일부 )을 알릴 수 없고 입력한 내용의 에코가 cat표시되지 않기 때문에 종료할 방법이 없습니다 .^Dicanon

다음을 수행할 수 있습니다.

_foo() {
  _values 'foo' "$(
    {
      s=$(stty -g)
      stty sane
      cat
      stty $s
    } < /dev/tty)"
  zle -I
}

즉, 실행하기 전에 터미널 장치를 예상된 상태로 두고 cat( ^D빈 줄을 누르거나 두 번 눌러 입력을 종료할 수 있음) cat실행 후 복원합니다. 우리는 zle에게 라인 규칙 라인 편집기에 입력한 내용의 에코로 인해 상황이 엉망이 되기 때문에 프롬프트와 버퍼를 다시 그려야 한다고 말합니다 zle -I(유효하지 않은).

답변2

이것은 아마도 너무 간단해서 cat읽는 데 /dev/tty오랜 시간이 걸릴 것입니다. _foo완성 으로

#compdef foo
_values 'foo' "$(promptfor)"

그리고promptfor

#!/usr/bin/env expect
set fh [open /dev/tty r+]
stty raw -echo
set key [read $fh 1]            ;# read from tty
puts stdout $key                ;# to ZSH
flush stdout
stty -raw echo

내 ZSH는 실행 중에 누르는 모든 키를 footab완료합니다 .promptfor

어떤 종류의 데몬이 있다면 ZSH와 데몬이 필요한 통신을 수행하는 데 사용할 수 있는 소켓과 같은 좀 더 이국적인 것을 원할 수 있습니다. readZSH에서는 임의의 파일 설명자나 보조 프로세스에서 읽을 수 있습니다.

관련 정보