이전 명령이 STDOUT에 쓰는 동안 STDIN에 다른 명령을 입력해도 안전합니까?


21

아마도 이것은 이전에 답변되었으므로 다른 답변에 대한 링크를 환영합니다 ...

bash다음과 같이 (쉘에서) 쉘 명령을 실행하면

make

그런 다음 출력 이 명령 make에서 스크롤되는 동안 첫 번째 명령 실행이 완료되기 전에 입력 하고 누르면 명령이 마지막으로 완료되면 다음 명령 이 즉시 실행됩니다.STDOUTmakemake checkentermakemake check

내 질문은 간단합니다.

  1. 이것이 위험한가요?
  2. 이런 종류의 급한 타이핑에서 예상치 못한 동작이 있습니까?
  3. 왜 이런 방식으로 작동합니까?

2
1. 나는 그것이 아니길 바래. 나는 몇 년 동안 이것을 해왔다!
John WH Smith

답변:


20

유닉스는 전이중이기 때문에 작동합니다. Ritchie가 The UNIX Time-sharing System : Retrospective 에서 말한 것처럼 :

사소한 것처럼 보이지만 일단 익숙해지면 놀라운 차이를 만드는 것은 미리 읽기와 함께 전이중 터미널 I / O입니다. 프로그램이 일반적으로 단일 문자가 아닌 선으로 사용자와 통신하지만 전이중 터미널 I / O는 시스템이 문자를 잃어 버리거나 깨뜨리지 않고 다시 입력하더라도 언제든지 입력 할 수 있음을 의미합니다. . 미리 읽기를 사용하면 모든 회선에 대한 응답을 기다릴 필요가 없습니다. 문서를 입력하는 좋은 타이피스트는 새로운 줄을 시작하기 전에 일시 정지해야 할 때 매우 실망합니다. 자신이 말하는 것을 알고 싶은 사람은 정보가 최고 속도가 아닌 비트 단위로 입력되어야한다면 응답 속도 저하가 심리적으로 확대됩니다.

[끝 인용]

다시 말해, 현대식 프로그램은 어떤 식 으로든 미리 먹거나 버린다. ssh그리고 apt-get두 가지 예입니다. 실행 중에 미리 입력하면 입력의 첫 부분이 사라 졌을 수 있습니다. 아마도 문제가 될 수 있습니다.

ssh remotehost do something that takes 20 seconds
mail bob
Dan has retired. Feel free to save any important files and then do
# ssh exits here, discarding the previous 2 lines
rm -fr *
.

bash fork()s와 execs 명령 후에 첫 번째 명령이 여전히 STDINbash 쉘에 첨부되어 있습니까? 대답이 아니오 인 것처럼 들립니다. bash는 다음 명령을 버퍼링하는 것 같습니다. 그 맞습니까?
111 ---

쉘에게 명령의 표준 입력을 재 지정하도록 지시하지 않는 한, 명령은 쉘과 동일한 표준 입력을 갖습니다. 입력 한 모든 내용을 읽는 첫 번째 프로세스에서 읽습니다. 셸은 명령이 실행되는 동안 의도적으로 아무것도 읽지 않고 명령이 중지 될 때까지 기다립니다. 를 사용하여 백그라운드에서 명령을 넣으면 상황이 더 복잡해집니다 &.
Mark Plotnick

그래서 STDINfifo 방식으로 처리됩니까? 배쉬의 자식 프로세스가 명시 적으로 상속 된 파일 핸들을 종료하지 않는 한 그리고 난 그 생각 STDIN다음이 여전히 추가 입력에서 읽어?
111 ---

예, 모든 터미널 입력은 FIFO를 처리합니다. 두 번째 질문을 이해하지 못했습니다. 자식 프로세스 (쉘이 호출 한 명령)는 일반적으로 stdin을 명시 적으로 닫지 않습니다 . 셸이 중단되고 명령이 원하는 모든 것을 읽게하면 자식이 중지되고 셸이 다시 읽습니다.
Mark Plotnick 님이

그래, 당신은 내 후속 질문을 매우 명확하게 해결했습니다. 감사합니다!
111 ---

12

당신이보고있는 기본 동작은 입력이 읽힐 때까지 어딘가에 버퍼에 앉아 있다는 것입니다 (잘 입력하면 결국 버퍼가 채워지고 무언가가 손실되어 많은 타이핑이 발생합니다). make로 실행되는 대부분의 항목은 STDIN에서 읽지 않으므로 버퍼에 남아 있습니다.

잘못된 명령은 입력을 읽는 위험이 있습니다. 예를 들어, make프롬프트 메시지를 표시 한 다음 다음 명령을 답으로 읽을 수 있습니다. 물론 그것이 얼마나 위험한지는 명령에 달려 있습니다. (이전 입력을 모두 버리고 이전 입력을 버릴 수도 있습니다.)

Makefile에서 일반적으로 사용되는 명령 중 하나는 TeX입니다. 오류가 발생하면 (사용자에게 절대로 묻지 않는 플래그가 제공되지 않은 경우) 계속할 것인지 묻는 메시지가 나타납니다.

더 나은 옵션은 다음을 실행하는 것 make && make check입니다..


8
  1. 반반으로, 첫 번째 명령 ( make예 :)에 성공적으로 완료된 두 번째 명령을 실행하면 안됩니다 . 예를 들어 make foo Enter> ./foo Enter 문제가 발생할 수 있습니다. make && make check첫 번째 명령이 성공한 경우에만 두 번째 명령이 실행되는 과 같은 입력 습관을 갖기를 원할 수도 있습니다 .
  2. 이론적으로 첫 번째 명령 (프로세스)이 두 번째 명령의 일부를 읽거나 터미널 입력 버퍼에서 제거 할 수 있습니다. 의 첫 6자를 먹은 경우 시스템에 존재하지 않는 make check명령을 실행하게 heck될 것입니다. 첫 번째 명령이 당신이 알고 신뢰하는 양성인 것이라면, 나는 즉시 아무런 문제도 보지 않습니다.
  3. 어떻게 / 왜 작동합니까? 시스템은 키보드 입력을 버퍼링합니다. 전자 메일과 비슷합니다. 짧은 시간에 한 사람에게 5 개의 메시지를 보낼 수 있으며받은 편지함에 앉아 읽을 때까지 기다립니다. 마찬가지로, 첫 번째 명령이 키보드에서 읽히지 않는 한, 입력 한 명령은 앉아서 쉘이 읽을 때까지 기다립니다. 버퍼링 할 수있는“type-ahead”의 양에는 제한이 있지만 일반적으로 수백 자 (수천이 아닌 경우)입니다.

2
포인트 1, 명령이 관련이없는 것으로 즉, 상상 ls하고 mount, 예를 들어 있습니다. 버퍼링 된 입력을 처리하는 방법을 이해하려고합니다. 답변 해주셔서 감사합니다.
111 ---
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.