여러 프로세스를 실행 중이고 프로세스 중 하나라도 실패하거나 존재할 경우(실패 시 오류, 그렇지 않으면 성공) 적절한 종료 코드로 종료하고 싶습니다.
또한 하위 프로세스가 종료되거나 실패하는 경우 다른 하위 프로세스도 종료되어야 합니다.
현재 작동하지 않는 솔루션(실은 단지 예일 뿐이며 다른 명령일 수 있음):
#!/bin/bash -e
# Run other process before start
sh ./bin/optimize.sh
trap 'exit' INT TERM
trap 'kill -INT 0' EXIT
# Run Schedule
sh ./bin/schedule.sh &
# Run a long running task
yarn task &
wait
./bin/schedule.sh
:
#!/bin/bash -e
while true; do
yarn schedule
sleep 30
done
무언가 yarn schedule
실패하면 모든 것이 올바르게 존재하게 됩니다. 하지만 + 또는 종료를 ctrl통해 프로세스를 종료 하면 프로세스가 계속 실행됩니다.cyarn task
yarn schedule
하위 프로세스가 무엇이든(bash, Yarn, PHP 또는 기타 프로세스) 어떻게 작동하게 할 수 있나요?
GNU 병렬성을 사용할 수 없습니다.
답변1
wait
내장 함수는 "아무거나 기다리지" 않고 "모두 기다리기" 때문에 쉘에서는 이것이 고통스럽습니다 . wait
매개변수가 없으면 모든 하위 프로세스가 종료될 때까지 기다리고 0을 반환합니다. wait
명시적인 프로세스 목록을 사용하는 경우 모든 하위 프로세스가 종료될 때까지 기다리고 마지막 인수의 상태를 반환합니다. 여러 자녀를 기다리고 자녀의 종료 상태를 확인하려면 다른 접근 방식을 취해야 합니다. wait
이는 어떤 자녀가 사망했는지 알고 있는 경우에만 종료 상태를 제공합니다.
한 가지 가능한 접근 방식은 전용 명명된 파이프를 사용하여 각 하위 항목의 상태를 보고하는 것입니다. 다음 코드 조각(테스트되지 않음!)은 가장 큰 하위 상태를 반환합니다.
mkfifo status_pipe
children=0
{ child1; echo 1 $? >status_pipe; } & children=$((children+1))
{ child2; echo 2 $? >status_pipe; } & children=$((children+1))
max_status=0
while [ $children -ne 0 ]; do
read -r child status <status_pipe
children=$((children-1))
if [ $status -gt $max_status ]; then
max_status=$status
fi
done
rm status_pipe
하위 쉘 중 하나가 상태를 보고하지 않고 죽으면 영원히 차단됩니다. 이는 일반적인 상황에서는 발생하지 않지만 서브쉘이 수동으로 종료되거나 서브쉘에 메모리가 부족할 경우 발생할 수 있습니다.
하위 항목 중 하나가 실패할 때 즉시 특정 작업을 수행하려면 if [ $status -gt $max_status ]; then …
로 바꾸십시오 if [ $status -ne 0 ]; then …
.
답변2
GNU 병렬에는 --halt
작업 중 하나가 완료되거나 종료되면 실행 중인 모든 작업이 종료되고 작업이 실패하면 false가 반환됩니다.
parallel --halt now,done=1 ::: 'sleep 1;echo a' 'sleep 2;echo b' ||
echo the job that finished failed
parallel --halt now,done=1 ::: 'sleep 1;echo a;false' 'sleep 2;echo b' ||
echo the job that finished failed
GNU Parallel이 설치되지 않은 시스템의 경우 일반적으로 다음 위치에 스크립트를 작성할 수 있습니다.가지다GNU Parallel, --embed
GNU Parallel을 스크립트에 직접 포함하는 데 사용됩니다.
parallel --embed > myscript.sh