Linux检查进程是否正在运行并对结果采取行动的脚本

pn9klfpd  于 12个月前  发布在  Linux
关注(0)|答案(8)|浏览(138)

我有一个经常失败的流程,有时会启动重复的示例。
当我运行:ps x |grep -v grep |grep -c "processname"时,我将得到:2这是正常的,因为该进程与恢复进程一起运行。
如果我得到0,我将希望启动该进程,如果我得到:4,我将希望停止并重新启动该进程
我需要一种方法来计算ps x |grep -v grep |grep -c "processname"的结果
然后设置一个简单的3选项功能

ps x |grep -v grep |grep -c "processname"
if answer = 0 (start process & write NOK & Time to log /var/processlog/check)
if answer = 2 (Do nothing & write OK & time to log /var/processlog/check)
if answer = 4 (stot & restart the process & write NOK & Time to log /var/processlog/check)

字符串
使用killall -9 process停止进程使用process -b -c /usr/local/etc启动进程
我的主要问题是找到一种方法来处理ps x |grep -v grep |grep -c "processname"的结果。
理想情况下,我希望将grep的结果作为脚本中的变量,如下所示:
process=$(ps x |grep -v grep |grep -c "processname")
如果可能的话。

hsgswve4

hsgswve41#

监视系统上进程是否正在运行的程序。

脚本存储在crontab中,每分钟运行一次。

如果进程未运行或进程多次运行,则此操作有效:

#! /bin/bash

case "$(pidof amadeus.x86 | wc -l)" in

0)  echo "Restarting Amadeus:     $(date)" >> /var/log/amadeus.txt
    /etc/amadeus/amadeus.x86 &
    ;;
1)  # all ok
    ;;
*)  echo "Removed double Amadeus: $(date)" >> /var/log/amadeus.txt
    kill $(pidof amadeus.x86 | awk '{print $1}')
    ;;
esac

字符串
0如果找不到进程,请重新启动它。
1如果找到进程,则一切正常。
*如果进程运行2个或更多,杀死最后一个。

一个更简单的版本。这只是测试进程是否正在运行,如果没有则重新启动它。

它只是测试pidof程序的退出标志$?。它将是0的进程正在运行,如果没有,则是1

#!/bin/bash
pidof  amadeus.x86 >/dev/null
if [[ $? -ne 0 ]] ; then
        echo "Restarting Amadeus:     $(date)" >> /var/log/amadeus.txt
        /etc/amadeus/amadeus.x86 &
fi

最后,一句俏皮话

pidof amadeus.x86 >/dev/null ; [[ $? -ne 0 ]] && echo "Restarting Amadeus:     $(date)" >> /var/log/amadeus.txt && /etc/amadeus/amadeus.x86 &


然后可以在crontab中使用它来像这样每分钟运行一次:

* * * * * pidof amadeus.x86 >/dev/null ; [[ $? -ne 0 ]] && echo "Restarting Amadeus:     $(date)" >> /var/log/amadeus.txt && /etc/amadeus/amadeus.x86 &


cccam oscam

ohtdti5x

ohtdti5x2#

我采用了@Jotne解决方案,并且工作得很好!例如,我的NAS中的mongodb服务器

#! /bin/bash

case "$(pidof mongod | wc -w)" in

0)  echo "Restarting mongod:"
    mongod --config mongodb.conf
    ;;
1)  echo "mongod already running"
    ;;
esac

字符串

nfzehxib

nfzehxib3#

我已经采用了你的脚本为我的情况约特内。

#! /bin/bash

logfile="/var/oscamlog/oscam1check.log"

case "$(pidof oscam1 | wc -w)" in

0)  echo "oscam1 not running, restarting oscam1:     $(date)" >> $logfile
    /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1 &
    ;;
2)  echo "oscam1 running, all OK:     $(date)" >> $logfile
    ;;
*)  echo "multiple instances of oscam1 running. Stopping & restarting oscam1:     $(date)" >> $logfile
    kill $(pidof oscam1 | awk '{print $1}')
    ;;
esac

字符串
当我在测试,我遇到了一个问题..我开始3额外的进程的oscam1与这一行:/usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1这让我与8进程oscam1.问题是这样的..当我运行脚本,它只杀死2进程的时间,所以我必须运行它3次,让它下降到2进程..
除了killall -9 oscam1之后是/usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1之外,在*)中,除了原始流程之外,还有什么更好的方法来重新部署所有流程吗?所以会有零停机时间?

gywdnpxw

gywdnpxw4#

如果你将awk '{print $1}'更改为'{ $1=""; print $0}',你将得到除第一个进程之外的所有进程。它将以字段分隔符(通常是空格)开头,但我不记得有任何关心。所以:

#! /bin/bash

logfile="/var/oscamlog/oscam1check.log"

case "$(pidof oscam1 | wc -w)" in

0)  echo "oscam1 not running, restarting oscam1:     $(date)" >> $logfile
    /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1 &
    ;;
2)  echo "oscam1 running, all OK:     $(date)" >> $logfile
    ;;
*)  echo "multiple instances of oscam1 running. Stopping & restarting oscam1:     $(date)" >> $logfile
    kill $(pidof oscam1 | awk '{ $1=""; print $0}')
    ;;
esac

字符串
值得注意的是,pidof路径似乎可以很好地处理没有空格的命令,但是如果您要查找(比如)名为myscript的python脚本,它显示在ps下,
根22415 54.0 0.4 89116 79076 pts/1 S 16:40 0:00 /usr/bin/python /usr/bin/myscript
只是一个FYI

zu0ti5jz

zu0ti5jz5#

'pidof'命令不会显示shell/perl/python脚本的pid。所以要找到我的Perl脚本的进程id,我必须使用-x选项,即'pidof -x perlscriptname'

qv7cva1a

qv7cva1a6#

我根本无法让案件工作。以下是我所拥有的:

#! /bin/bash

logfile="/home/name/public_html/cgi-bin/check.log"

case "$(pidof -x script.pl | wc -w)" in

0)  echo "script not running, Restarting script:     $(date)" >> $logfile
#  ./restart-script.sh
;;
1)  echo "script Running:     $(date)" >> $logfile
;;
*)  echo "Removed duplicate instances of script: $(date)" >> $logfile
 #   kill $(pidof -x ./script.pl | awk '{ $1=""; print $0}')
;;
esac

字符串
现在rem case action命令只是为了测试脚本。上面的pidof -x命令返回'1',case语句返回'0'的结果。
有人知道我哪里做错了吗?
通过将以下内容添加到我的BIN/BASH脚本中解决了这个问题:PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/bin

uelo1irk

uelo1irk7#

如果您正在寻找一种更现代的方法来检查服务是否正在运行(这对任何旧进程都不起作用),那么 systemctl 可能是您正在寻找的。
下面是基本命令:

systemctl show --property=ActiveState your_service_here

字符串
这将产生非常简单的输出(根据服务是否正在运行,将显示以下两行之一):

ActiveState=active
ActiveState=inactive


如果你想知道你能得到的所有属性:

systemctl show --all your_service_here


如果你更喜欢这样的话:

systemctl show --all your_service_here | sort


以及执行它的完整代码:

service=$1
result=`systemctl show --property=ActiveState $service`
if [[ "$result" == 'ActiveState=active' ]]; then
    echo "$service is running" # Do something here
else
    echo "$service is not running" # Do something else here
fi

kxxlusnw

kxxlusnw8#

如果您使用的是CentOS,则无需编写脚本并设置cron作业。这里是确保systemd服务在失败时重新启动的最聪明的方法之一。请对/usr/lib/systemd/system/mariadb.service进行以下更改
然后在文件中的[Service]部分下,添加以下两行:

Restart=always
RestartSec=3

字符串
保存文件后,我们需要重新加载守护进程配置,以确保systemd知道新文件

systemctl daemon-reload


阅读以下链接了解完整步骤-https://jonarcher.info/2015/08/ensure-systemd-services-restart-on-failure/

相关问题