출력 리디렉션 및 프로세스 대체를 실험하는 동안 우연히 다음 명령과 그 결과 출력을 발견했습니다.
me@elem:~$ echo foo >>(cat);echo 열 술집 나 @elem:~$ foo
(예, 끝에 빈 줄 바꿈은 의도적인 것입니다.)
따라서 bash echo의 막대는 일반적인 프롬프트, echo의 foo, echo의 개행 문자를 인쇄하고 거기에 커서를 둡니다. Enter를 다시 누르면 새 줄에 프롬프트가 인쇄되고 그 뒤에 커서가 남습니다(누군가 빈 명령줄에서 Enter를 누를 때 예상되는 대로).
나는 파일 설명자에 foo를 쓰고, cat을 읽고 foo를 에코하고, 두 번째는 echo bar에 기록한 다음 명령 프롬프트로 돌아갈 것으로 예상합니다. 그러나 이것은 분명히 사실이 아니다.
무슨 일인지 설명해 줄 수 있는 사람이 있나요?
답변1
시간에 따라 프롬프트 foo
이전 bar
, 이후 또는 이후에도 콘텐츠가 표시 될 수 있습니다 . bar
일관된 타이밍을 위해 약간의 지연을 추가합니다.
$ echo foo > >(sleep 1; cat); echo bar; sleep 2
bar
foo
$
bar
즉시 나타나고, foo
1초 후에 나타나고, 1초 후에 다음 프롬프트가 나타납니다.
무슨 일이 일어나는지는 bash가 백그라운드에서 프로세스 교체를 수행한다는 것입니다.
- 기본 bash 프로세스는 실행을 위해 하위 쉘을 시작
sleep 1; cat
하고 이에 대한 파이프를 설정합니다. - 기본 bash 프로세스가 실행됩니다
echo foo
. 이는 파이프의 버퍼를 채우지 않으므로echo
명령은 차단 없이 종료됩니다. - 기본 bash 프로세스가 실행됩니다
echo bar
. - 기본 bash 프로세스 시작 명령
sleep 2
. - 동시에 서브쉘은 명령을 실행합니다
sleep 1
. - 약 1초 후에
sleep 1
자식 프로세스로 돌아갑니다. 하위 프로세스는 계속해서 실행됩니다cat
. cat
입력을 출력(화면에 표시됨)으로 복사하고 그 반대로 복사합니다.- 서브쉘이 작업을 마치고 종료됩니다.
- 1초 후에
sleep 2
다시 돌아오세요. 기본 셸 프로세스가 실행을 완료하고 다음 프롬프트가 표시됩니다.
답변2
이 효과를 얻기 위해 프로세스를 교체할 필요는 없습니다. 이 시도:
( echo foo | cat & )
거의 동일한 결과를 얻을 수 있으며(아무것도 없습니다 bar
. 연습으로 남겨 두겠습니다) 동일한 이유가 있습니다. 두 경우 모두 cat
백그라운드 작업으로 시작됩니다. 내 경우에는 이것이 분명하다. 프로세스 교체의 경우에도 명확합니다(이름 파일 설명자에 첨부된 별도의 프로세스임). 그러나 그다지 명확하지 않을 수도 있습니다.
bash
다음 프롬프트를 인쇄하기 전에 하위 프로세스가 반드시 종료되는 것은 아닙니다. 출력이 버퍼링되므로 종료되기 전에는 아무것도 출력되지 않습니다. 이 시점에서 bash는 방금 stderr에 인쇄되었으며 이제 인쇄 및 래핑 후에 $
백그라운드 프로세스가 종료됩니다.foo