이 스크립트의 축어적 사본이 있습니다.
#!/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
상태에서 두 명령이 병렬로 실행되기 때문에 작동합니다 .cmd1
cmd2
그리고bash는 파이프라인이 완료된 것으로 간주하기 전에 두 가지가 모두 완료될 때까지 기다립니다.
비교해 보면 cmd1 > >(cmd2)
bash가 추가 명령을 계속하기 전에 완료될 때까지 기다리지 않는다는 점을 제외하면 거의 동일합니다 cmd2
(이 경우 "zoom"을 인쇄한 다음 종료하고 대화형 bash가 프롬프트를 인쇄하도록 허용) cmd2
. 그보다 훨씬 더 많은 시간이 cmd1
걸리면 여러분이 관찰한 놀라운 경쟁 상황이 발생합니다.