检查在shell中运行的jar文件

7

我有一个Java的jar程序,希望能够在我的机器启动时运行。最好的方法是,shell脚本每60秒检查一次以确保该程序正在运行。但是,在Centos上如何检查程序是否在运行,这似乎不起作用?

这是我当前的.sh文件内容:

#!/bin/bash

while [ true ]
do
    cnt=`ps -eaflc --sort stime | grep /home/Portal.jar |grep -v grep | wc -l`
    if(test $cnt -eq 3);
    then
        echo "Service already running..."
    else
        echo "Starting Service"
        java -jar /home/Portal.jar >> /dev/null &
    fi
    sleep 1m
done

到目前为止,我使用这个作为参考。


1
你说它似乎没有起作用,是什么意思?具体问题是什么? - Robin Green
它总是进入启动服务。它无法检测程序是否已经在运行。 - Sixthpoint
7个回答

4

将您的进程ID存储在文件中,并检查该进程。

#!/bin/bash

while [ true ]
do
    pid=$(cat /tmp/portal.pid)
    if [[ -n "$pid" && $(ps -p $pid | wc -l) -eq 2 ]]
    then
        echo "Service already running..."
    else
        echo "Starting Service"
        java -jar /home/Portal.jar >> /dev/null &
        echo $! > /tmp/portal.pid
    fi
    sleep 1m
done

/tmp 会在重新启动时被清除,在这种情况下没问题。


将pid存储在文件中并不是很干净的做法。其他进程可能会更改该文件,文件可能会损坏,或者该进程甚至可能获得新的pid。有很多事情可能会出错,因此我真的建议使用其他解决方案。 - Tobias

4
根据您的程序功能,可能有更或更少智能的方法来检查它。例如,如果您有一个服务器,它将监听某个端口。

然后可以使用以下内容:

netstat -an | fgrep tcp | fgrep LISTEN | fgrep :87654   # or whatever your port is

能够胜任的工作应该具备如下基本要求。

其次,还有lsof,它也可以检测侦听端口。

最后,您可以连接并发出伪请求。例如,对于http服务器,您可以使用lynxcurl。对于具有非标准协议的服务器,您可以编写一个唯一目的是连接到服务器以查看其是否存在的小客户端程序。


1
我更倾向于让该进程退出,然后使用crontab每1分钟运行该进程;这将检查它是否正在运行,否则就停止脚本。
#!/bin/sh
declare -a devId=( "/Path/To/TestJar.jar Test1" "/Path/To/TestJar.jar Test2" ) #jarfile with pathname and Test as argument
# get length of an array
arraylength=${#devId[@]}
# use for loop to read all values and indexes
for (( i=1; i<${arraylength}+1; i++ ));
do
y=${devId[$i-1]}
cnt=`ps -eaflc --sort stime | grep "$y" |grep -v grep | wc -l`
if [ $cnt = 0 ]
then
java -jar $y& > /dev/null
b=$(basename $y)
echo $b 
#DO SOME OPERATION LIKE SEND AN EMAIL OR ADD TO LOG FILE
continue
elif [ $cnt != 0 ]
then
echo 'do nothing'
fi
done

1
我几个月前也做了同样的情境。我的任务是确保在Linux服务器上分发的jar Java程序能够24/7运行。 我的程序是基于控制台的,启动后会执行某些操作然后停止。 我编写了一个Shell脚本,它启动程序,等待结束,然后在无限循环中重新启动应用程序。 我安装了runit,创建了一个服务,并将此脚本提供为运行脚本。运行非常好。 通常,Shell脚本确保Java程序正在运行,而runit确保启动脚本(即我们的脚本)正在运行。
您可以在这里找到有价值的信息:http://smarden.org/runit/faq.html

0
你可以使用jps命令。它会返回系统中正在运行的JVM。

0
为什么您认为$cnt应该等于3?如果进程已经在运行,它不应该等于1吗?

执行 pgrep java 命令时,发现有 3 个进程正在运行。 - Sixthpoint
问题似乎出在:test: -eq: 需要单目运算符 - Sixthpoint
1
但是 pgrep java 并不是你的命令实际执行的内容!你正在搜索一个特定的应用程序!我会将其写成 if [ $cnt -eq 1 ]。你需要尝试一些脚本的部分,直到它们正确地工作,而不仅仅是运行你的脚本并祈祷。 - Robin Green

0
我创建了以下脚本来监控我的应用程序jar是否正在运行。 在这种情况下,我的应用程序jar正在8080端口上运行。
#!/bin/bash
check=$(netstat -an | grep 8080 | wc -l)
if [[ $check -eq 0 ]];then
    echo "jar is not running..."
    /usr/bin/java -jar /path/to/target/application.jar >> /dev/null &
else
    echo "it is running"
fi

我正在使用cronjob通过每分钟执行shell脚本来监控jar应用程序。

$ crontab -e

文件末尾
* * * * * /bin/bash monitor-jar.sh /dev/null 2>&1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接