Bash – 백그라운드 프로세스 종료 수신 대기

Bash – 백그라운드 프로세스 종료 수신 대기

일부 서버를 시작하려면 다음 bash 스크립트가 있습니다.

services=(
    account-service
    reminder-service
    activity-service
    socket-service
    chat-service
    web-app
)


for s in "${services[@]}"; do

 (
   set -e;
   cd "$s"
   git pull
   npm start || exit 1 # always fails
 ) &

 sleep 1;

done

wait;

때때로 git pull명령이 실패합니다. 그러나 결함은 로그 깊은 곳에 있으며 항상 명확하지는 않습니다. 서브셸의 명령 중 하나가 1로 종료되면 전체 스크립트를 어떻게 중단합니까?

답변1

글쎄요, 아마도 wait다음과 같이 진술을 변경해 보세요:

while true; do
    wait -n || exit 1          # if one of the background jobs failed, abort
    [[ "$(jobs)" ]] && break   # exit this loop if no more jobs
done

완전히 테스트되지 않았습니다. jobs이것이 비대화형 쉘에서 예상대로 작동하는지 잘 모르겠습니다 .

답변2

여기에는 몇 가지 질문이 있습니다.

  1. 하위 셸의 명령이 실패하면 전체 스크립트가 중단됩니다.
  2. 발생하는 오류에 대한 가시성을 높입니다.

두 번째부터 시작하겠습니다. 이 질문에는 답변의 시드가 포함되어 있습니다. 오류는 기록되지만 로그 내용은 사용자에게 명확하지 않습니다. 따라서 오류를 임시 로그 파일에 기록하고 마지막에 표시합니다.

서비스 = (
    계정 서비스
    알림 서비스
    이벤트 서비스
    소켓 서비스
    채팅 서비스
    웹 애플리케이션
)
오류 파일=$(mktemp)

"${services[@]}"의 for s;
 (
   세트이;
   CD "$s"
   자식 당겨  || {
        echo "$s" >> "$errfile"
        1번출구
   }
   에코 "$cmd" |
 )&
 잠 1
완벽한

기다리다

if [ -s "$errfile" ]
그 다음에
        echo "다음 서비스에 오류가 있습니다:"
        고양이 "$errfile"
필리핀 제도
rm -f "$errfile"

문제 #1을 해결하는 가장 간단한 방법은 서브셸의 코드를 주기적으로 확인 [ -s "$errfile" ]하고 문제가 발생하면 자체를 중단하는 것입니다. 보다 야심 찬 접근 방식은 기본(상위) 프로세스가 하위 프로세스의 PID를 추적하고 해당 프로세스에 신호를 보내도록 하는 것입니다. 가 없는지 확실하지 않습니다 wait -n. (아마도 오류가 있는 자식이 부모에게 신호를 보내서 wait. )

관련 정보