시스템 정보 :
macOS Sierra 10.12.6
zsh 5.4.2 (x86_64-apple-darwin16.7.0)
GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.3.0)
내가 만든 간단한 예제를 찾으려면 맨 아래 의 예제 로 스크롤하십시오 .
참고 : 나는 큰 zsh
사용자가 아닙니다 .
및 의 fzf
키 바인딩을 보고있었습니다 .bash
zsh
둘 다 어떻게 변수 명령을 실행하는지 주목하십시오 $(__fzfcmd)
. __fzfcmd
기본적 fzf
으로 stdout 으로 출력 되고 매개 변수 대체 fzf
는 출력 결과로 나오는 명령 ( ) 만 실행 합니다.
bash
와 zsh
스크립트의 한 가지 차이점 bash
은 출력을 추가로 파이프 $(__fzfcmd)
하지만 zsh
배열 내에서 캡처한다는 것입니다. 내 생각에 때문에 문제입니다 zsh
때 더 파이프의 출력 fzf
이되지 입력 할 수있는 fzf
프로세스가에 파이프 fzf
모든 표준 입력을하지 않습니다. 당신의 유일한 선택은 ^Z
또는 ^C
입니다. ^C
어떤 이유로 프로세스를 배경으로 보인다. 또는 어쩌면 그들은 배열에서 그것을 원했을 때 그것을 실행할zle vi-fetch-history
수 있었을 것 입니다. 이 bash
버전은 키 바인딩에서 마술을 수행합니다."\e^": history-expand-line
지금 fzf
은 중요하지 않습니다. tty
이 문제를 일으키기 위해 매개 변수 대체에 의해 호출되는 프로그램을 필요로하는 것처럼 보입니다 . 간단한 예를 보여 드리겠습니다.
tty
이 문제를 일으킬 수있는 다른 명령은 다음과 같습니다 zsh
.
- vipe (파이프 중간에서 편집기 실행)
'vim -'
(vidin은 vidin과 비슷하지만 stdout으로 출력되지는 않습니다.)
아래의 예에서 나타나는 모든 경우 교체 vipe
와 vim -
별도 설치하지 않으려면을. vim -
편집기 내용을 표준 출력으로 출력하지 않는다는 것을 기억하십시오 vipe
.
예 :
1) echo 1 | vipe | cat # works in both bash and zsh
2) echo 1 | $(echo vipe) | cat # works in bash only. zsh problem with no output until I hit `^C`:
^C
zsh: done echo 1 |
zsh: suspended (tty output) $(echo vipe) |
zsh: interrupt cat
# seems like the process is backgrounded. I can still see it in jobs command
3) cat <(echo 1 | $(echo vipe)) # zsh and bash has the problem. I'm guessing because
# the file isn't finished writing and cat is
# blocking vipe's tty output
# both their `^C` output is just:
^C # nothing special, as expected
4) cat < <(echo 1 | $(echo vipe)) # works in both bash and zsh
5) echo 1 | $(echo vipe) > >(cat) # works in both bash and zsh
# The following don't have and input pipe to vipe.
# Type something then send EOF with ^D
6) vipe | cat # works for both
7) $(echo vipe) | cat # works for both
지금, 나는 대부분의 이유를 궁금 해서요 2)
에 대한 문제가 zsh
있지만하지 않는 bash
이유 4)
및 5)
수정에 대한 문제 zsh
.
zsh
이 문제에 대한 요구 사항은 내가 제목에 넣은 것과 정확히 일치하는 것 같습니다.
- 입력 파이프
tty
출력 이있는 변수 / 매개 변수 대체에 의해 실행되는 명령- 출력 파이프
최신 정보
zsh
이 문제가 발생하지 않는 다른 해결 방법을 추가했습니다 5)
. 그것은으로 직접 4)
리디렉션하는 대신 프로세스 대체 를 사용하여 리디렉션되는 파일로 리디렉션 합니다.stdout
stin
stdin
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
ps
알 수 있듯이 이러한 경우 껍질이 얼거나 붙어 있지 않습니다 . 그들은 단순히 정상적인 방식으로 자식 프로세스를 기다리고 있습니다. 그리고 자식 프로세스가 일시 중지되거나 종료되면 정상적인 방식으로 입력하라는 메시지가 표시됩니다. 질문 제목과 본문에는 암시 적 거짓 전제가 포함됩니다. "왜 껍질이 얼어 붙습니까?" 쉘이 실제로 얼지 않는 경우에는 대답 할 수없는로드 된 질문 입니다. 이 암시 적 전제를 제거하는 데 더 좋은 질문이 있습니다.