Linux脚本,用于检查进程是否正在运行并对结果执行操作

时间:2013-11-23 13:08:36

标签: linux bash process grep

我有一个定期失败的过程&有时会启动重复实例..

当我跑步时: 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")

如果可能的话。

8 个答案:

答案 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/