我正在尝试创建一个脚本,在后台启动一堆作业,然后等待所有作业运行完成。
#!/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&
Run Code Online (Sandbox Code Playgroud)
为了确保该脚本将等待其所有子进程,即使在生成子进程时出现问题,我也会使用而trap cleanup EXIT不是仅cleanup在最后使用。
但是当我在不同的 shell 中运行此脚本时,我得到以下结果:
$ 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
$
Run Code Online (Sandbox Code Playgroud)
在 Bash 中,trap 命令似乎被完全忽略。原因可能是什么?有办法解决吗?
man bash-builtins说了一些关于进入外壳时被忽略的信号无法被捕获的信息,但我不知道这如何适用于这种情况......
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
}
Run Code Online (Sandbox Code Playgroud)