假如你写了个 shell 脚本,来运行目标程序,比如 java,然后再用 supervisor 来配置启动这个 shell 脚本。
cat start.sh
1 2 3 4 5 6 7 8 9 | #!/bin/bash # Prepare the JVM command line ... $JAVA_EXECUTABLE $JAVA_ARGS # Clean up ... |
cat supervisor.conf
1 2 3 4 5 6 7 | [program:testjava] command = / home / kyle / testjava / start.sh directory = / home / kyle / testjava autorestart = true user = ubuntu redirect_stderr = true stdout_logfile = / var / log / supervisor / testjava.log |
这时候会有个问题,当 supervisor stop 你的程序的时候,shell 脚本退出了,然后程序却还在。
这是因为 TERM 信号被 shell 进程接收到了,但是 shell 并没有把信号转给子进程。
有个简单的解决办法,就是在程序运行命令前面,加上 exec,这样程序进程会替换当前的 bash shell 进程。
1 2 3 | #!/bin/bash ... exec $JAVA_EXECUTABLE $JAVA_ARGS |
但是这个方案有个问题,如果想在 shell 脚本中,捕捉到程序退出,然后做一些事情,就没有办法了。
这时候可以使用 wait,以及 trap 命令来实现,具体可以搜索下这两个命令的文档。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/bin/bash _term() { echo "Caught SIGTERM signal!" kill -TERM "$child" 2> /dev/null } trap _term SIGTERM echo "Doing some initial work..." ; /bin/start/main/server --nodaemon & child=$! wait "$child" |
或
1 2 3 4 5 6 7 8 9 10 | #!/bin/bash ... trap 'kill -TERM $PID' TERM INT $JAVA_EXECUTABLE $JAVA_ARGS & PID=$! wait $PID trap - TERM INT wait $PID EXIT_STATUS=$? ... |
参考资料: