스크립트가 종료되지 않는 이유가 혼란스럽습니다.

스크립트가 종료되지 않는 이유가 혼란스럽습니다.

이 스크립트의 축어적 사본이 있습니다.

#!/usr/bin/env bash


handle_json(){
  while read line; do
    cat <<EOF
{"@json-stdio":true,"value":{"mark":"$1","v":"$line"}}
EOF
    done;
}

( echo; echo; echo 'du results:'; exit 0 ) > >(handle_json foo);

echo "zoom"

실행하면 다음과 같은 결과가 나타납니다.

여기에 이미지 설명을 입력하세요.

자체적으로 종료되지 않기 때문에 ctrl-C를 사용하여 수동으로 종료해야 합니다.

내가 원하는 것은 서브셸의 표준 출력을 bash 함수로 보내 JSON이 출력을 문자열화하도록 하는 것입니다(지금은 특수 문자 이스케이프에 대해 걱정할 필요가 없습니다).

이 스크립트가 자체적으로 종료되지 않는 이유를 아는 사람이 있습니까?

고쳐 쓰다:

이것은 실제로 내가 원하는 작업을 수행합니다.

( echo; echo; echo 'du results'; ) |  handle_json 'foo';

echo "zoom"

위의 내용은 리디렉션/프로세스 대체 대신 파이프 연산자를 사용합니다. 파이프라인 운영자가 여기서 일할 거라고는 예상하지 못했습니다. 누군가 왜/어떻게 작동하는지 설명할 수 있습니까?

답변1

내가 아는 한, 당신의 스크립트는했다종료합니다. 쉘이 프롬프트를 인쇄한 직후 프로세스 교체가 백그라운드에서 실행 및 인쇄를 완료합니다.

이를 방지하는 한 가지 방법은 다음을 사용하는 대신 함수를 파이프하는 것입니다 > >(...).

( echo; echo; echo 'du results:'; exit 0 ) | handle_json foo

이는 를 쓸 때 표준 출력이 표준 입력에 연결된 cmd1 | cmd2상태에서 두 명령이 병렬로 실행되기 때문에 작동합니다 .cmd1cmd2그리고bash는 파이프라인이 완료된 것으로 간주하기 전에 두 가지가 모두 완료될 때까지 기다립니다.

비교해 보면 cmd1 > >(cmd2)bash가 추가 명령을 계속하기 전에 완료될 때까지 기다리지 않는다는 점을 제외하면 거의 동일합니다 cmd2(이 경우 "zoom"을 인쇄한 다음 종료하고 대화형 bash가 프롬프트를 인쇄하도록 허용) cmd2. 그보다 훨씬 더 많은 시간이 cmd1걸리면 여러분이 관찰한 놀라운 경쟁 상황이 발생합니다.

관련 정보