셸은 명령에 입력 된“재설정”이 표시되지 않지만 어떻게 되었습니까?


57

내 문제는 Bash 쉘이 입력 한 문자 표시를 중단한다는 것입니다. 그래도 명령을 읽습니다.

나는이 문제를 꽤 많이 겪었고 그 원인을 이해하지 못합니다. 나는 그것을 해결하는 방법을 알고 있지만, 내가 문제에서 벗어나는 길을 "부두"할 때 그것을 정말로 좋아하지 않는다.

이 문제를 겪은 두 가지 방법을 설명하겠습니다.

특정 프로세스 인 http://pythonpaste.org/script/를 실행 중이며 때로는 중지하거나 제어를 중단하면 셸에 다시 제공됩니다. 그런 다음 쉘에 명령을 입력하면 입력 한 문자가 표시되지 않습니다. Enter 키를 누르면 명령 제출됩니다. 예를 들어 :

  • "ls"를 입력합니다
  • 나는 빈 프롬프트 만 보이고 더 이상 아무것도 보이지 않습니다.
  • Enter 키를 누르면 파일 목록이 표시됩니다. 즉, 명령 실행됩니다.
  • "reset"명령을 주면 쉘이 다시 정상적으로 작동하기 시작합니다

이것이 일어나는 두 번째 방법은 다음과 같은 명령을 내릴 때입니다.

$ grep foo * -l | xargs vim

grep을 사용하여 특정 패턴이있는 파일을 찾은 다음 grep에서 발생하는 모든 파일을 열고 싶습니다. 이것은 매력처럼 작동합니다 (바람직하지는 않지만). 그러나 Vim을 종료하면 쉘에 입력 한 문자가 표시되지 않습니다. 재설정 명령으로 문제가 해결됩니다.

내 생각에 두 문제 모두 근본적인 이유가 있지만 그 이유가 무엇인지 또는 어떤 것인지에 대해서는 다소 혼란스러워합니다.

이 문제에 대한 검색은 설명 자체가 모호하고 어려운 검색어가 없기 때문에 문제가됩니다.

편집하다

주는

stty --all

John S. Gruber의 요청에 따라 다음과 같은 결과를 얻었습니다 (가독성을 위해 편집 된 공백).

speed 0 baud;
rows 53;
columns 186;
line = 0;
intr = <undef>;
quit = <undef>;
erase = <undef>;
kill = <undef>; 
eof = <undef>;
eol = <undef>; 
eol2 = <undef>; 
swtch = <undef>; 
start = <undef>; 
stop = <undef>; 
susp = <undef>;
rprnt = <undef>; 
werase = <undef>; 
lnext = <undef>; 
flush = <undef>; 
min = 0; 
time = 0;
-parenb 
-parodd cs8 
-hupcl 
-cstopb cread 
-clocal 
-crtscts
-ignbrk 
-brkint 
-ignpar 
-parmrk 
-inpck 
-istrip 
-inlcr 
-igncr 
-icrnl 
-ixon 
-ixoff 
-iuclc 
-ixany 
-imaxbel 
-iutf8
-opost 
-olcuc 
-ocrnl 
-onlcr 
-onocr 
-onlret 
-ofill 
-ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig 
-icanon 
-iexten 
-echo 
-echoe 
-echok 
-echonl 
-noflsh 
-xcase 
-tostop 
-echoprt 
-echoctl 
-echoke

2
이 경우 stty --all귀하의 질문에 결과 를 입력 하고 넣으십시오. 에코는 꺼져있는 tty 특성입니다. Vim은 실행 중에이 작업을 수행하며 터미널도 원시 모드로 설정합니다. 종료되면 터미널 설정 자체를 재설정해야합니다. vim이 실행 중일 때 i편집기를 삽입 모드로 만드는 명령 을 에코하지 않으려 고합니다 . 이 설정은 tty 장치에 입력 한 내용을 처리하는 방법을 알려줍니다. vim이 실행되는 동안 무엇이 에코되어야하는지 에코 처리합니다.
John S Gruber

포 그라운드에서 실행될 때 Zope (CTRL + C 사용)을 중지하고 ipdb 디버깅 세션에있을 때 동일한 증상이 나타납니다.
Mark van Lent

나도 그 문제를 가지고 생각 @MarkvanLent
닐스 BOM이

@JohnSGruber stty --all질문에 대한 결과를 추가했습니다 . 미리 감사드립니다!
Niels Bom

답변:


68

쉘에서 쉘 또는 대부분의 프로그램을 실행할 때 입력 한 모든 내용은 커널의 tty 서브 시스템에 의해 사용자의 터미널로 에코됩니다. 문자 지우기, Ctrl + R, Ctrl + Z 등을위한 다른 특수 처리도 있습니다.

명령 행에서 실행되는 특정 프로그램 (특히 편집기)은이를 필요로하지 않습니다. 이러한 이유로 tty (터미널) 장치에 대한 IOCTL 호출로 커널에이 동작을 원하지 않는다는 신호를 보냅니다. 그들은 특별한 캐릭터가 특별한 일을하기를 원하지 않습니다. 대신 커널에 "원시"모드를 요청합니다. 특히, vim과 같은 편집기는 다양한 "에코 설정"을 해제합니다. 이 모든 것은 컴퓨터의 직렬 회선에있는 실제 tty 터미널이나 Alt + Ctrl + F1의 가상 터미널 또는 GUI에서 gnome-terminal과 같은 것을 실행할 때 얻을 수있는 가상 터미널에 적용됩니다.

이러한 프로그램은 종료 편집기 명령을 입력하거나 (Control + C에서) 신호를 가져 와서 종료하기 전에 사용중인 가상 tty에서 변경 한 모드를 재설정해야합니다.

그들이 이것을 제대로 수행하지 못하면 tty는 당신이 발견 한 재미있는 상태로 남아 있습니다. 프로그램이 터미널을 재설정하지 못할 reset수 있으므로 사용자가 복구 할 수 있도록 명령이 작성되었습니다.

인터럽트가 실행중인 파이썬 소프트웨어와 충돌한다고 가정합니다. 그 프로그램이 터미널을 재설정 할 기회를 얻지 못하거나 단순히 그렇게하지 못하는 것 같습니다.

vim의 경우, 예제를 실행하면 설명 한 것과 동일한 동작이 나타납니다. 또한 "Vim : 경고 : 입력이 터미널에서 온 것이 아닙니다"라는 메시지가 표시됩니다 (재설정하면 사라짐). 이것은 vim이 쉘에서 정상적으로 시작되지 않기 때문입니다. 대신 'grep'및 'xargs'명령은 greptto 에서 파일 이름을 전달하기 위해 일반적으로 tty가 사용하는 표준 입력을 사용했습니다 xargs.

게시 된 결과에서 stty -a"-echo"를 볼 수 있으며 이것이 문제임을 확인합니다. 신호를 정상적으로 처리 할 수없는 방식으로 vim을 죽인다면 아마도 같은 문제를 보게 될 것입니다.

이 문제는 https://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-shell-in-weird-state에 설명되어 있습니다 .

vim 케이스의 해결책은 xargs를 피하고 대신 사용하는 것입니다.

 vim $(grep foo * -l)

여기에서 파일 목록은 xargs와 마찬가지로 쉘에 의해 구성되지만 쉘은 vim을 호출하며, 이는 tty에 직접 연결됩니다. 오류 출력 파일에 경고 메시지가 전송되고 vim은 tty 설정을 올바르게 설정하고 재설정합니다.

여기에 더 많은 참조가 있고 여기 에 또 다른 흥미로운 참조가 있습니다 . 또 다른 흥미로운 해결책은 https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour 에 대한 답변으로 제공 됩니다 .


철저한 설명에 감사드립니다. 이것이 작동하지 않는 완전한 이유는 꽤 깊은 토끼 구멍 (tty, ioctl 등)처럼 보이므로 완전히 이해한다고 말할 수는 없지만 더 이상 부두가 아니므로 다시 한번 감사드립니다!
Niels Bom

완료되기 위해 grep foo * -l | vim -문제없이 실행할 수 있습니다. 그래서 문제는 grep과 xargs가 아니라 xargs에만 있다고 생각 합니다. 동의하겠습니까?
Niels Bom

1
grep이나 xargs에는 문제가 없습니다. stdin이 더 이상 tty로 설정되지 않는다는 사실에 문제가 있습니다. 이것도 실패`true | vi / tmp / afile1. 참고 문헌 중 하나는 vim이 stdin을 stdout (여전히 tty)으로 설정한다는 것을 언급합니다. stdin이 이러한 상황에서 / dev / null로 설정 되었기 때문입니다. 그렇게하면 vim은 에코 및 기타 설정을 기억하고 재설정 할 수 있지만 그렇지 않습니다. 나는 이것이 vim의 문제라고 생각한다.
존 S 그루버

내가 이것에 부딪 칠 때 이것은 매우 도움이되었습니다. 그것은 무작위로 느꼈지만, 깨끗하게 종료되거나 파이프를 사용하지 않은 vi로 무언가를하려고 할 때 항상 그렇습니다.
Michael Mathews

1
감사합니다! 마지막으로 ctrl-c 후 OS X bash에서 복구하는 방법을 알아 냈습니다 git add -p!
Steve Jansen

0

시스템에서 새 사용자를 시작하고 (새로 깨끗한 사용자를 만들고 로그인해야 함) 문제가 있는지 확인합니다. 그렇지 않은 경우-터미널 또는 X11 설정입니다.


새로운 사용자를 추가하고 grep foo * -l | xargs vim명령으로 이것을 테스트했습니다 . 문제가 여전히 존재합니다. 내 X11 설정이 터미널이 btw에 반응하는 방식에 어떻게 영향을 줄 수 있는지 정확하게 이해하지 못합니다. 그것에 대해 자세히 설명해 주시겠습니까? 감사!
Niels Bom
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.