Ubuntu 终止由 bash 启动的 java 程序

Ubuntu 终止由 bash 启动的 java 程序

我在 Ubuntu 上终止 Java 程序时遇到问题。我创建了以下初始化脚本:

#!/bin/sh

### BEGIN INIT INFO
# Provides:          control ...
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: ...
# Description:       ...
### END INIT INFO

DAEMON_PATH="/mnt/Data/wstlm"
DAEMON=startWstlm
DAEMONOPTS=""

NAME=wstlm
DESC="My daemon description"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

case "$1" in
start)
        printf "%-50s" "Starting $NAME..."
        cd $DAEMON_PATH
        PID=`./$DAEMON $DAEMONOPTS > /dev/null 2>&1 & echo $!`
        echo "Saving PID" $PID " to " $PIDFILE
        if [ -z $PID ]; then
            printf "%s\n" "Fail"
        else
            echo $PID > $PIDFILE
            printf "%s\n" "Ok"
        fi
;;
status)
        printf "%-50s" "Checking $NAME..."
        if [ -f $PIDFILE ]; then
            PID=`cat $PIDFILE`
            if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
                printf "%s\n" "Process dead but pidfile exists"
            else
                echo "Running"
            fi
        else
            printf "%s\n" "Service not running"
        fi
;;
stop)
        printf "%-50s" "Stopping $NAME"
            PID=`cat $PIDFILE`
            cd $DAEMON_PATH
        if [ -f $PIDFILE ]; then
            kill -9 $PID
            printf "%s\n" "Ok"
            rm -f $PIDFILE
        else
            printf "%s\n" "pidfile not found"
        fi
;;

restart)
    $0 stop
    $0 start
;;

*)
        echo "Usage: $0 {status|start|stop|restart}"
        exit 1
esac

这个初始化脚本将目录改变为我的程序,执行的startWstlm的内容是:

#!/bin/sh
echo date +"%Y/%m/%d %T"- 启动 WSTLm 1>>/mnt/Data/wstlm/wstlm.log
java -Djavax.net.ssl.trustStore=jssecacerts -jar /mnt/Data/wstlm/myProgram.jar

我将 init 脚本添加到了 init.d。如果我调用

sudo 服务 myProgram 启动

程序正常启动。但如果我使用

sudo 服务 myProgram 停止

程序没有关闭。只有启动我的 java 程序的 bash 命令被终止。

执行停止之前:

1 根 /bin/sh ./startWstlm
2 根 java -Djavax.net.ssl.trustStore=jssecacerts -jar /mnt/Data/wstlm/myProgram.jar
3 根 java -Djavax.net.ssl.trustStore=jssecacerts -jar /mnt/Data/wstlm/myProgram.jar
4 根 java -Djavax.net.ssl.trustStore=jssecacerts -jar /mnt/Data/wstlm/myProgram.jar

执行停止后:

(注意这个 bash 被杀死了)
2 root java -Djavax.net.ssl.trustStore=jssecacerts -jar /mnt/Data/wstlm/myProgram.jar
3 root java -Djavax.net.ssl.trustStore=jssecacerts -jar /mnt/Data/wstlm/myProgram.jar
4 root java -Djavax.net.ssl.trustStore=jssecacerts -jar /mnt/Data/wstlm/myProgram.jar

(顺便问一下:这个jar为什么有多个进程?)

所以问题是我无法停止我的程序。这有点烦人。有人知道吗?

答案1

首先,不要使用kill -9;简单的kill就足够了。其次,参见这一页详细解释了当父进程被要求退出时如何终止子进程。在这种情况下,startWstim需要在 Java 程序退出之前终止它。

最后,也许更简单的是省去startWstim,而是直接在初始化脚本中执行它包含的命令:

start)
    printf "%-50s" "Starting $NAME..."
    cd $DAEMON_PATH
    echo "$(date +"%Y/%m/%d %T") - start WSTLm" >> /mnt/Data/wstlm/wstlm.log
    java -Djavax.net.ssl.trustStore=jssecacerts -jar /mnt/Data/wstlm/myProgram.jar &
    PID=$!

请注意,您不需要子 shell 来获取 Java 程序的进程 ID,并且您需要捕获命令的输出date以便将其打印到日志文件。

相关内容