버전 5.3.1을 사용하고 있습니다 zsh
.
% zsh --version
zsh 5.3.1 (x86_64-pc-linux-gnu)
C-x r
구성을 다시 로드하기 위해 키 시퀀스를 사용하여 키 바인딩을 정의하려고 합니다 zsh
. 감사해요@길스, 내 코드에 다음 코드를 포함합니다 ~/.zshrc
.
reread_zshrc () {
. ~/.zshrc
}
zle -N reread_zshrc
bindkey '^Xr' reread_zshrc
을 클릭할 때를 제외하고는 작동하지만 C-x r
오류 zsh
에 대해 불평합니다.
stty: 'standard input': Bad file descriptor
stty: 'standard input': Bad file descriptor
dircolors: /home/user/.dircolors: Bad file descriptor
다음과 같은 최소값으로 이러한 오류를 재현할 수 있습니다 zshrc
.
stty -ixon
stty quit undef
eval "$(dircolors -b ~/.dircolors)"
reread_zshrc () {
. ~/.zshrc
}
zle -N reread_zshrc
bindkey '^Xr' reread_zshrc
다음은 이 2개의 stty
명령을 포함하는 위치와 이 dircolors
명령이 내 zshrc
.
stty -ixon
터미널 드라이버가 터미널 흐름 제어를 해석 C-s
하고 C-q
작동하는 것을 방지합니다. 기본적으로 C-s
터미널을 고정하고 C-q
고정을 해제합니다. 터미널을 정지하지 않고도 쉘이나 텍스트 편집기의 키 바인딩을 C-s
사용할 수 있습니다.C-q
stty quit undef
SIGQUIT
누를 때 터미널 드라이버가 신호를 보내는 것을 방지합니다 C-\
. 마찬가지로, 포그라운드 프로세스를 종료하지 않고도 이 키를 키 바인딩에 사용할 수 있습니다.
eval "$(dircolors -b ~/.dircolors)"
ls
에서 구성을 읽어오도록 명령을 요청합니다 ~/.dircolors
. 명령의 출력에 따라 색상을 사용자 정의할 수 있습니다 ls
.
zsh
이 3줄이 현재 쉘에서 이미 실행되었다면 다시 할당되지 않도록 보호해야 할 것 같습니다. 하지만 어떤 조건을 써야할지 모르겠습니다.
if <stty and dircolors haven't been executed already>; then
stty -ixon
stty quit undef
eval "$(dircolors -b ~/.dircolors)"
if
zsh
또한 이러한 오류 메시지 를 대화형 셸에서 실행해도 아무런 문제가 발생하지 않으므로 이러한 오류 메시지를 더 잘 이해하고 싶습니다 . 왜 이 키 바인딩에서만 오류가 발생합니까?
답변1
zle
위젯 에서는 zsh
stdin을 닫는 것 같습니다. 나는 zsh
이러한 위젯의 명령이 사용자 입력을 직접적으로 방해하는 것을 피하고 싶지만 /dev/null에서 stdin을 리디렉션하는 것이 더 현명할 것입니다(이 문제는 다음 버전에서 수정될 예정입니다).
표준 입력(파일 설명자 0)이 닫히면 명령으로 연 첫 번째 파일이 표준 입력이 된다는 의미입니다(파일 설명자가 첫 번째 무료 파일에서 할당되기 때문입니다).
에서는 dircolors
오류가 발생합니다. dircolors
당신의 것을 열고 ~/.dircolors
그것이 이미 표준 입력(fd가 반환하는 것이기 때문에 open()
)이라는 것을 알지 못한 채 표준 입력으로 만들어 보십시오. 따라서 dup2(0,0)
(stdin을 자신에게 복사하는 것) 실패하고 EBADF 오류를 보고합니다 dircolors
.
stty
표준 입력에서 열린 터미널에 대한 설정을 지정합니다. 여기서는 stdin이 닫혀 있으므로 stty
오류가 반환됩니다.
여기서 표준 입력을 터미널에 복원하도록 위젯을 변경할 수 있습니다.
reread_zshrc () . ~/.zshrc < $TTY
하지만 위젯 내에서 tty 설정을 변경하는 것은 zle
(귀하의 명령이 무엇인지는 모르지만 stty
) 나쁜 생각이라는 점을 명심하십시오. zle
tty는 줄 편집을 위한 특수 모드로 설정되어 있고 사용자가 조작하고 싶지 않기 때문입니다. (그리고 편집이 끝나면 일반 tty 설정이 어쨌든 복원되므로 변경 사항이 손실됩니다).
따라서 stdin을 만들어야 할 수도 있지만 /dev/null
(실제로 터미널에서 작업을 수행하고 싶지 않기 때문에) stty
여전히 불평할 것이므로( /dev/null
tty 장치가 아니기 때문에) stderr를 /dev/ null로 리디렉션할 수도 있습니다. 이러한 오류 메시지를 숨기려면(비록 숨겨지더라도모두잘못된 정보):
reread_zshrc() . ~/.zshrc < /dev/null 2> /dev/null