我有以下要运行的脚本。问题是它没有优雅地退出;当我按Ctrl-C
时,只有罗盘终止,但runserver
仍然在后台进行,需要手动杀死。有没有办法让这两个优雅地退出?如果没有通过Ctrl-C
,我还应该用其他东西来一起杀死这些进程吗?
谢谢!
#!/bin/bash
cd /path/venv
source ./bin/activate
service gunicorn stop
cd /path/www/static/sass_sorting
compass watch &
/path/venv/djo/manage.py runserver &
答案 0 :(得分:1)
-p
的{{1}}选项将返回仍在运行的后台作业列表。您可以将其传递给信号处理程序中的jobs
。
kill
如果可能有您要保持运行的作业,请保存您可能要杀死的后台作业的进程ID。
#!/bin/bash
trap 'kill $(jobs -p)' SIGINT
cd /path/venv
source ./bin/activate
service gunicorn stop
cd /path/www/static/sass_sorting
compass watch &
/path/venv/djo/manage.py runserver &
有一个不可避免的竞争条件,因为一个过程可能总是在你检查它是否仍在运行之间以及你何时真正试图杀死它时完成,所以你可以简单地忽略来自#!/bin/bash
trap 'kill $p1 $p2' SIGINT
cd /path/venv
source ./bin/activate
service gunicorn stop
cd /path/www/static/sass_sorting
compass watch & p1=$!
/path/venv/djo/manage.py runserver & p2=$!
的任何错误“没有这样的过程”。
答案 1 :(得分:0)
使用可以终止进程的命令捕获SIGINT,并使用一个循环来检查进程是否仍然存在。
#!/bin/bash
cd /ssdhome/development/matthew-server/venv
source ./bin/activate
service gunicorn stop
cd /ssdhome/development/matthew-server/www/static/sass_sorting
compass watch &
p1=$!
/ssdhome/development/matthew-server/venv/djo/manage.py runserver &
p2=$!
trap 'kill "$p1"; kill "$p2"' SIGINT
while kill -s 0 "$p1" || kill -s 0 "$p2"; do
wait "$p1"; wait "$p2"
done &>/dev/null
而不是默认信号SIGTERM,如果它不能很好地结束你的应用程序,你也可以尝试SIGHUP或SIGABRT:
trap 'kill -s SIGHUP "$p1"; kill -s SIGHUP "$p2"' SIGINT