이 문제이것은 또 다른 관련 질문에 영감을주었습니다. 시작한다고 상상해보세요
% nohup a.sh &
그런 다음 완료 시 실행됩니다 b.sh
(예: 처리될 출력. 둘 다 완료하는 데 몇 시간이 걸리는 장기 실행 프로세스입니다.)a.sh
b.sh
a.sh
a.sh
b.sh
기본적으로 시뮬레이션하고 싶습니다
% nohup a.sh && b.sh
b.sh
하지만 시작할 때 추가하는 것을 잊어버렸습니다 a.sh
. 이것이 달성될 수 있습니까? 바람직하게는 zsh에서.
답변1
프로세스를 시작한 쉘이 여전히 이를 인식하고 있는 경우(이를 수행하려고 시도하는 경우 jobs
) 내장 쉘은 wait
프로세스가 완료될 때까지 기다릴 수 있습니다. 다음과 같이 작동할 수 있습니다.
$ jobs
[1] nohup a.sh
$ wait -f %1 && nohup b.sh &
셸에서 연결이 끊어지면 pidwait
명령이 비슷한 방식으로 작동할 수 있습니다. 단, 첫 번째 프로세스의 종료 값을 캡처하지 못하고 첫 번째 프로세스가 실패하더라도 두 번째 프로세스를 실행할 수 있습니다. 이는 done 다르게 와 일치하지 않습니다 &&
.
답변2
상위 프로세스(또는 상위 프로세스가 있거나 init
종료된 경우 하위 수확기)만이 프로세스의 종료 상태를 검색할 수 있습니다.
명령을 실행한 셸에서 명령을 기다렸다가 성공하면 b.sh
백그라운드에서 시작할 수 있습니다.a.sh
wait $pid && nohup b.sh &
zsh에서 또는:
wait -f "$pid" && { nohup b.sh & }
최신 버전의 bash에서는(프로세스가 단순히 중지되면 -f
for가 반환되지 않습니다. 이것이 bash의 기본 동작입니다).wait
zsh
하지만 wait
포그라운드에서 실행되어야 합니다. 백그라운드에서 실행되는 경우 하위 셸 프로세스에 있으므로 더 이상 실행 중인 프로세스의 상위 프로세스가 아닙니다 nohup a.sh
.
자신의 것이 아닌 하위 프로세스의 종료 상태를 검색하는 한 가지 방법은 디버거와 인터셉트 _exit()
또는 exit_group()
동등한 시스템 호출을 사용하는 것입니다.
예를 들어 Linux에서는 다음과 같이 할 수 있습니다.
ret=$(strace -qqqa0 -e signal=none -e exit_group -p "$pid" 2>&1 | grep -Po '\(\K\d+')
macos에 상응하는 명령에는 truss
or dtrace
명령이 포함될 수 있지만 테스트할 시스템이 없습니다.