다음 코드가 명령을 완료하지 못하는 이유는 무엇입니까 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
표시되지 않기 때문에 종료할 방법이 없습니다 .^D
icanon
다음을 수행할 수 있습니다.
_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는 실행 중에 누르는 모든 키를 foo
tab완료합니다 .promptfor
어떤 종류의 데몬이 있다면 ZSH와 데몬이 필요한 통신을 수행하는 데 사용할 수 있는 소켓과 같은 좀 더 이국적인 것을 원할 수 있습니다. read
ZSH에서는 임의의 파일 설명자나 보조 프로세스에서 읽을 수 있습니다.