여기에 뭔가가 빠졌나 봐요.
#!/bin/bash
timeout 5 sleep 10 &
parent_pid=$( ps --pid $! -o ppid --no-headers )
timeout_pid=$( pgrep --parent $parent_pid timeout )
wait $timeout_pid
echo "exit code: $?"
스크립트를 호출 wait-pid
하고 다음을 실행합니다.
$ ./wait-pid
exit code: 124
이것이 제가 기대하는 것입니다. 프로세스를 timeout
종료 하고 124로 종료하면 충실하게 반환됩니다.sleep
wait
하지만 초기 명령에 파이프를 추가하면 다음과 같습니다.
timeout 5 sleep 10 | cat &
parent_pid=$( ps --pid $! -o ppid --no-headers )
timeout_pid=$( pgrep --parent $parent_pid timeout )
wait $timeout_pid
echo "exit code: $?"
이제 나는 다음을 얻습니다:
$ ./wait-pid
exit code: 0
wait
기다리고 있는 프로세스의 종료 코드를 반환하면 안 됩니다 timeout
. 그러면 종료 코드가 여전히 124여야 하지 않나요?
이것은 bash 4.4.20(1) 릴리스 버전입니다.
답변1
나는 bash 메일링 리스트에 있는 매우 박식한 Greg Wooledge로부터 답장을 받았습니다. 핵심 요소는 다음과 같습니다.
wait 명령은 "비동기 명령"이라고도 알려진 셸의 직접 하위 프로세스에서만 작동합니다. 비동기 명령이 파이프인 경우 원래 sh 기능 세트로 대체됩니다. 비동기 명령의 종료 상태는 파이프라인의 마지막 명령의 종료 상태이며, 다른 명령의 종료 상태는 단순히 삭제됩니다.
timeout
그래서 파이프에 있을 때 종료 코드를 얻지 못하는 이유입니다 .
내가 원하는 동작을 얻는 방법은 임시 파일을 사용하여 비동기 코드에서 종료 코드를 캡처하는 것입니다. 그것은 다음과 같습니다:
{
timeout 5 sleep 10 | cat
echo "${PIPESTATUS[@]}" > "$tempfile"
} &
wait