我有一个定期失败的过程&有时会启动重复实例..
当我跑步时:
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")
如果可能的话。
答案 0 :(得分:63)
这是一个用于监视系统上的进程是否正在运行的脚本。
脚本存储在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 &
答案 1 :(得分:8)
我采用了@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
答案 2 :(得分:4)
我已根据我的情况采用了你的脚本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
在我测试的时候,我遇到了一个问题..
我用这一行开始了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
,*)
除了原始流程之外还有更好的方法吗?那么停机时间会为零吗?
答案 3 :(得分:0)
如果将awk'{print $ 1}'更改为'{$ 1 =“”; print $ 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
仅供参考
答案 4 :(得分:0)
'pidof'命令将不显示shell / perl / python脚本的pid。因此,要查找我的Perl脚本的进程ID,我必须使用-x选项,即'pidof -x perlscriptname'
答案 5 :(得分:0)
我根本无法处理案件。 这是我的东西:
#! /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
现在只执行case操作命令来测试脚本。上面的pidof -x命令返回“ 1”,case语句返回“ 0”的结果。
有人知道我要去哪里错吗?
通过将以下内容添加到我的BIN / BASH脚本中来解决此问题: PATH = $ PATH:/ usr / local / sbin:/ usr / local / bin:/ usr / sbin:/ usr / bin:/ sbin:/ bin
答案 6 :(得分:0)
如果您正在寻找一种更现代的方法来检查服务是否正在运行(这不适用于任何旧进程),那么 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
答案 7 :(得分:0)
如果您使用的是 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/