假如你写了个 shell 脚本,来运行目标程序,比如 java,然后再用 supervisor 来配置启动这个 shell 脚本。
cat start.sh
#!/bin/bash # Prepare the JVM command line ... $JAVA_EXECUTABLE $JAVA_ARGS # Clean up ...
cat supervisor.conf
[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 进程。
#!/bin/bash ... exec $JAVA_EXECUTABLE $JAVA_ARGS
但是这个方案有个问题,如果想在 shell 脚本中,捕捉到程序退出,然后做一些事情,就没有办法了。
这时候可以使用 wait,以及 trap 命令来实现,具体可以搜索下这两个命令的文档。
#!/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"
或
#!/bin/bash ... trap 'kill -TERM $PID' TERM INT $JAVA_EXECUTABLE $JAVA_ARGS & PID=$! wait $PID trap - TERM INT wait $PID EXIT_STATUS=$? ...
参考资料: