현재 zsh 쉘이 `dircolors` 및 `stty` 명령을 실행했는지 테스트하는 방법은 무엇입니까?

현재 zsh 쉘이 `dircolors` 및 `stty` 명령을 실행했는지 테스트하는 방법은 무엇입니까?

버전 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 undefSIGQUIT누를 때 터미널 드라이버가 신호를 보내는 것을 방지합니다 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위젯 에서는 zshstdin을 닫는 것 같습니다. 나는 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) 나쁜 생각이라는 점을 명심하십시오. zletty는 줄 편집을 위한 특수 모드로 설정되어 있고 사용자가 조작하고 싶지 않기 때문입니다. (그리고 편집이 끝나면 일반 tty 설정이 어쨌든 복원되므로 변경 사항이 손실됩니다).

따라서 stdin을 만들어야 할 수도 있지만 /dev/null(실제로 터미널에서 작업을 수행하고 싶지 않기 때문에) stty여전히 불평할 것이므로( /dev/nulltty 장치가 아니기 때문에) stderr를 /dev/ null로 리디렉션할 수도 있습니다. 이러한 오류 메시지를 숨기려면(비록 숨겨지더라도모두잘못된 정보):

reread_zshrc() . ~/.zshrc < /dev/null 2> /dev/null

관련 정보