출력 리디렉션 및 프로세스 대체를 실험하는 동안 다음 명령과 결과 출력을 발견했습니다.
me @ elem : ~ $ echo foo>> (고양이); 에코 바 바 me @ elem : ~ $ foo
(예, 끝에 빈 줄 바꿈은 의도적입니다.)
bash echo ‘s bar, 일반적인 프롬프트, echo ‘s foo, echo는 개행 문자를 출력하고 커서를 거기에 둡니다. Enter 키를 다시 누르면 프롬프트가 새 줄에 인쇄되고 커서가 그 뒤에 있습니다 (누군가가 빈 명령 줄에서 Enter 키를 칠 때 예상대로).
파일 설명자에 foo를 쓰고 cat에서 읽은 다음 echo ‘s foo, 두 번째 echo echo ‘s bar, 명령 프롬프트로 돌아갈 것으로 예상했습니다. 그러나 그것은 사실이 아닙니다.
누군가 무슨 일인지 설명해 주시겠습니까?
답변
타이밍에 따라 프롬프트 foo
전 bar
, 후 bar
또는 심지어 후에 표시 될 수 있습니다 . 일정한 타이밍을 얻으려면 약간의 지연을 추가하십시오.
$ echo foo > >(sleep 1; cat); echo bar; sleep 2
bar
foo
$
bar
즉시 나타난 다음 foo
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
돌아옵니다. 기본 셸 프로세스 실행이 완료되고 다음 프롬프트가 표시됩니다.
답변
그 효과를 얻기 위해 프로세스 대체가 필요하지 않습니다. 이 시도:
( echo foo | cat & )
당신은 동일한 결과를 얻을 수 있습니다 ( bar
;; 운동으로 남겨 두겠습니다). 같은 이유로. 두 경우 모두 cat
백그라운드 작업으로 시작됩니다. 내 라인에서, 그것은 명백합니다. 프로세스 대체의 경우 명시 적입니다-이름 파일 설명자에 연결된 별도의 프로세스입니다. 그러나 분명하지 않을 수도 있습니다.
bash
다음 프롬프트 를 인쇄 하기 전에 하위 프로세스가 반드시 종료되는 것은 아닙니다 . 또한 출력이 버퍼링되므로 종료 될 때까지 아무 것도 출력하지 않습니다. 이 시점에서 bash는 $
stderr에 방금 인쇄 되었으며 이제 인쇄 foo
및 개행 후에 백그라운드 프로세스가 종료됩니다 .