【问题标题】:Run jar file as Daemon on Linux Ubuntu在 Linux Ubuntu 上将 jar 文件作为守护进程运行
【发布时间】:2014-08-07 18:22:27
【问题描述】:

我想在我的 Teamspeak3 中安装一个机器人,并在启动时将此机器人作为守护程序运行。我编写了自己的脚本并将其复制到 init.d,然后将其与 update-rc.d 添加到默认值。

#!/bin/sh
#
# JTS3ServerBot Script
#
USER="ts"
NAME="jts3"
DIR="/home/ts/jts3/"
case $1 in
    start)
        echo "Starting ${NAME} ..."
        if [ ! -f $DIR/pid ]; then
            sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
            echo $! > $DIR/pid
            echo "${NAME} started ..."
        else
            echo "${NAME} is already running ..."
        fi
    ;;
    stop)
        if [ -f $DIR/pid ]; then
            PID=$(cat $DIR/pid);
            echo "Stopping ${NAME} ..."
            kill $PID;
            echo "${NAME} stopped ..."
            rm $DIR/pid
        else
            echo "${NAME} is not running ..."
        fi
    ;;
    restart)
        if [ -f $DIR/pid ]; then
            PID=$(cat $DIR/pid);
            echo "Stopping ${NAME} ...";
            kill $PID;
            echo "${NAME} stopped ...";
            rm $DIR/pid

            echo "Starting ${NAME} ..."
            sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
            echo $! > $DIR/pid
            echo "${NAME} started ..."
        else
            echo "${NAME} is not running ..."
        fi
    ;;
esac

生成了一个 pid 文件,但如果我尝试使用此 pid 终止进程,则会收到该进程不存在的错误。如果我使用top,则没有列出 pid 的进程。

root@vps-1023645-8462:~# service jts3 start
Starting jts3 ...
jts3 started ...
root@vps-1023645-8462:~# cat /home/ts/jts3/pid 
10206
root@vps-1023645-8462:~# kill 10206
bash: kill: (10206) - No such process

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND           
 1762 ts        20   0 1881m  14m 3408 S    0  1.4 215:47.28 ts3server_linux    
32356 ts        20   0  164m 1576 1336 S    0  0.2   0:09.85 tsdnsserver_lin 

【问题讨论】:

  • 您正在捕获sudo 的PID,而不是java...sudo 可能在nohup 运行您的java 命令后退出后退出。
  • @twalberg 这应该是一个答案,而不是评论。
  • 另外,为了避免捕获sudo PID,你应该使用ps -ef | grep JTS3ServerMod.jar | awk '{print $2}'。这应该会给你正在运行的进程的 PID。
  • @FlorinStingaciu 不确定我是否想回答这个问题,因为它并没有真正解决问题,它只是指出问题出在哪里......一个合适的解决方案可能需要了解正在使用什么发行版,以及是否可以使用 start-stop-daemon 或其他类似的脚本/工具...
  • @twalberg 这不是原因 - 默认情况下 sudo 不会分叉(它只是 exec 并且只有一个 pid)。这种情况下的问题是一个虚假的参数标志,正如我在回答中详述的那样。

标签: linux bash shell jar daemon


【解决方案1】:

我为我的问题找到了另一种解决方案。我使用 upstart(仅适用于 Ubuntu)将我的 jar-File 作为守护程序运行。 Upstart 管理 PID。只需将myservice.conf 添加到/etc/init(不是/etc/inid.d),守护程序将在启动时启动,您可以将其作为服务进行管理。您不必使文件可运行或其他任何东西

例如,您可以照常管理服务

service myservice restart
service myservice status
...

我的配置文件:

description "myservice"
author "your name"

start on runlevel [3]
stop on shutdown

expect fork

script   
    cd /home/username/
    sudo -u username java -jar /home/username/myservice/myservice.jar >/home/username/myservice.log 2>&1
    emit myservice_running
end script

这个解决方案非常简单,在我的 Ubuntu 12.04 服务器上运行良好。

【讨论】:

    【解决方案2】:

    你在这一行有一个错误:

    sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>>/dev/null >>/dev/null&
    

    您似乎在混合使用sudosu 的语法。在 1.8 版之前,sudo 没有 -c 选项 - 您只需在任何其他选项之后给它运行命令即可。在 1.8 中有一个 -c 选项,但它不是用于指定命令(它是用于将资源使用限制为给定登录类的资源使用)。 sudo 正在打印有关此无效语法的错误消息,但您没有看到它,因为您将所有输出重定向到 /dev/null

    只需删除-c 即可形成有效命令:

    sudo -u $USER nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
    

    另外,您可以通过使用2>&1 语法将stderr 发送到与stdout 相同的句柄来稍微简化命令,并且在写入/dev/null 时不需要附加模式:

    sudo -u $USER nohup java -jar $DIR/JTS3ServerMod.jar $DIR >/dev/null 2>&1 &
    

    【讨论】:

    • 我更改了我的脚本,但进程仍然没有启动
    • 尝试在没有重定向的情况下运行,看看修改后的命令是否打印和错误消息。
    • sudo -u $USER nohup java -jar $DIR/JTS3ServerMod.jar 你的意思是我说的没有重定向吗?因为什么都没发生
    猜你喜欢
    • 2013-03-09
    • 2011-07-21
    • 2012-01-18
    • 2014-04-26
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多