Почему «trap EXIT» не работает в фоновых заданиях в Bash? - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь создать сценарий, который запускает несколько заданий в фоновом режиме, а затем ожидает завершения всех из них.

#!/bin/sh

cleanup() {
    wait
    echo cleanup
}

do_work() {
    sleep 2
    echo done "$@"
}

run() {
    trap cleanup EXIT
    do_work 1 &
    # ... some code that may fail ...
    do_work 2 &
    # I can't just call cleanup() here because of possible early exit
}

# The script itself runs in the background too.
run&

Чтобы этот сценарий ожидал всех своих дочерних элементов. процессов, даже если что-то идет не так при их порождении, я использую trap cleanup EXIT вместо просто cleanup в конце.

Но когда я запускаю этот скрипт в разных оболочках, я получаю следующие результаты:

$ for sh in zsh dash 'busybox ash' bash; do echo "$sh:"; $sh script.sh; sleep 3; echo; done
zsh:
done 1
done 2
cleanup

dash:
done 1
done 2
cleanup

busybox ash:
done 2
done 1
cleanup

bash:
done 2
done 1

$

В Bash команда trap, похоже, полностью игнорируется. Что может быть причиной этого? Любой способ исправить это?

man bash-builtins говорит что-то о сигналах, игнорируемых при входе в оболочку, которые не могут быть захвачены, но я понятия не имею, как это относится к этой ситуации ...

1 Ответ

2 голосов
/ 30 марта 2020

Просто позвоните exit в конце run:

run() {
    trap cleanup EXIT
    do_work 1 &
    # ... some code that may fail ...
    do_work 2 &
    # I can't just call cleanup() here because of possible early exit
    exit
}
...