[unix] bash가 “>> ()”를 처리하는 방법

출력 리디렉션 및 프로세스 대체를 실험하는 동안 다음 명령과 결과 출력을 발견했습니다.

    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, 명령 프롬프트로 돌아갈 것으로 예상했습니다. 그러나 그것은 사실이 아닙니다.

누군가 무슨 일인지 설명해 주시겠습니까?



답변

타이밍에 따라 프롬프트 foobar, 후 bar또는 심지어 후에 표시 될 수 있습니다 . 일정한 타이밍을 얻으려면 약간의 지연을 추가하십시오.

$ echo foo > >(sleep 1; cat); echo bar; sleep 2
bar
foo
$

bar즉시 나타난 다음 foo1 초 후에 다음 프롬프트가 다시 나타납니다 .

bash는 백그라운드에서 프로세스 대체를 실행합니다.

  1. 기본 bash 프로세스는 실행하기 위해 서브 쉘을 시작 sleep 1; cat하고 파이프를 설정합니다.
  2. 기본 bash 프로세스가 실행 echo foo됩니다. 파이프의 버퍼를 채우지 않기 때문에 echo명령은 차단없이 종료됩니다.
  3. 기본 bash 프로세스가 실행 echo bar됩니다.
  4. 기본 bash 프로세스는 명령을 실행합니다 sleep 2.
  5. 한편, 서브 쉘은 명령을 시작합니다 sleep 1.
  6. 약 1 초 후에 sleep 1하위 프로세스로 돌아갑니다. 하위 프로세스가 실행을 진행합니다 cat.
  7. cat 입력을 출력 (화면에 표시됨)에 복사하고 리턴합니다.
  8. 서브 쉘이 작업을 완료하면 종료됩니다.
  9. 1 초 후에 다시 sleep 2돌아옵니다. 기본 셸 프로세스 실행이 완료되고 다음 프롬프트가 표시됩니다.

답변

그 효과를 얻기 위해 프로세스 대체가 필요하지 않습니다. 이 시도:

( echo foo | cat & )

당신은 동일한 결과를 얻을 수 있습니다 ( bar;; 운동으로 남겨 두겠습니다). 같은 이유로. 두 경우 모두 cat백그라운드 작업으로 시작됩니다. 내 라인에서, 그것은 명백합니다. 프로세스 대체의 경우 명시 적입니다-이름 파일 설명자에 연결된 별도의 프로세스입니다. 그러나 분명하지 않을 수도 있습니다.

bash다음 프롬프트 를 인쇄 하기 전에 하위 프로세스가 반드시 종료되는 것은 아닙니다 . 또한 출력이 버퍼링되므로 종료 될 때까지 아무 것도 출력하지 않습니다. 이 시점에서 bash는 $stderr에 방금 인쇄 되었으며 이제 인쇄 foo및 개행 후에 백그라운드 프로세스가 종료됩니다 .


답변