Reputation: 433
I am trying to create a script that starts a bunch of jobs in the background and then waits until all of them run to completion.
#!/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&
To ensure that this script will wait for all its child processes, even if something goes wrong while spawning them, I use trap cleanup EXIT
instead of just cleanup
at the end.
But when I run this script in different shells, I get the following results:
$ 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
$
In Bash the trap command seems to be completely ignored. What might be the reason for that? Any way to fix it?
man bash-builtins
says something about signals ignored upon entry to the shell that cannot be trapped, but I have no idea how that applies to this situation...
Upvotes: 3
Views: 1116
Reputation: 2610
Just call exit
at the end of 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
}
Upvotes: 6