[英]Linux Script to check if process is running and act on the result
我有一个经常失败的过程,有时会启动重复的实例..
当我运行: 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")
如果可能的话。
用于监视系统上的进程是否正在运行的程序。
脚本存储在crontab
,每分钟运行一次。
#! /bin/bash
case "$(pidof amadeus.x86 | wc -w)" 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 &
cccam oscam
我采用了@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
我已经根据我的情况采用了你的脚本 Jotne。
#! /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
在测试时,我遇到了一个问题..我用这一行启动了 oscam1 的 3 个额外进程: /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1
这给我留下了 oscam1 的 8 个进程。 问题是这样的..当我运行脚本时,它一次只杀死 2 个进程,所以我必须运行 3 次才能将它降到 2 个进程。
除了killall -9 oscam1
后跟/usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1
,在*)
中还有什么更好的方法可以将 killall 分开从原始过程? 那么会有零停机时间吗?
如果您将 awk '{print $1}' 更改为 '{ $1=""; 打印 $0}' 您将获得除第一个之外的所有进程作为结果。 它将以字段分隔符(通常为空格)开头,但我不记得 killall 关心。 所以:
#! /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 的字符串,该脚本出现在ps 喜欢
根 22415 54.0 0.4 89116 79076 pts/1 S 16:40 0:00 /usr/bin/python /usr/bin/myscript
仅供参考
'pidof' 命令不会显示 shell/perl/python 脚本的 pid。 所以要找到我的 Perl 脚本的进程 ID,我必须使用 -x 选项,即 'pidof -x perlscriptname'
我根本无法得到案例。 这是我所拥有的:
#! /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 操作命令只是为了测试脚本。 上面的 pidof -x 命令返回“1”,case 语句返回“0”的结果。
任何人都知道我哪里出错了?
通过将以下内容添加到我的 BIN/BASH 脚本来解决它:PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
如果您正在寻找一种更现代的方法来检查服务是否正在运行(这不适用于任何旧进程),那么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
如果您使用的是 CentOS,则无需编写脚本并设置 cron 作业。 这是确保 systemd 服务在失败时重新启动的最明智的方法之一。 对 /usr/lib/systemd/system/mariadb.service 进行以下更改
然后在文件的 [Service] 部分下,添加以下 2 行:
Restart=always
RestartSec=3
保存文件后,我们需要重新加载守护程序配置以确保 systemd 知道新文件
systemctl daemon-reload
阅读以下链接了解完整步骤 - https://jonarcher.info/2015/08/ensure-systemd-services-restart-on-failure/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.