여기에 뭔가가 빠졌나 봐요.
#!/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
를 종료 sleep
하고 124로 종료되어 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