2010-05-25 115 views
53

我写了一个bash脚本来检查进程是否正在运行。它不起作用,因为ps命令总是返回退出代码1.当我从命令行运行ps命令时,$?被正确设置,但在脚本中它始终是1.任何想法?bash脚本来检查运行进程

#!/bin/bash 
SERVICE=$1 

ps -a | grep -v grep | grep $1 > /dev/null 
result=$? 
echo "exit code: ${result}" 
if [ "${result}" -eq "0" ] ; then 
    echo "`date`: $SERVICE service running, everything is fine" 
else 
    echo "`date`: $SERVICE is not running" 
fi 

猛砸版本:GNU的bash,版本3.2.25(1)-release下(x86_64-红帽Linux的GNU的)

+0

检查过程是否存在的最佳方法:http:// stackoverflow。com/questions/3043978/how-to-check-if-a-process-id-pid-exists – 2016-06-07 15:43:48

+0

你能否检查一下,看看你是否从grep命令获得非空输出而不是依赖返回值? – 2010-05-25 09:22:17

+0

我试过这个,并有类似的问题。输出不被考虑在内。下面的代码: #/斌/庆典 SERVICE = $ 1 OUTPUT = $(PS -a | grep的-v grep的| grep的$ 1) 回声$ OUTPUT 如果[ “$ {#OUTPUT}” - gt 0];然后 echo“'date':$ SERVICE service running,everything is fine” else echo“'date':$ SERVICE is not running” fi – elasticsecurity 2010-05-25 09:44:13

回答

12

试戴BASH版本3.2.29您的版本,运行良好。不过,你可以按照上面的建议做一些事情,例如:

#!/bin/sh 

SERVICE="$1" 
RESULT=`ps -a | sed -n /${SERVICE}/p` 

if [ "${RESULT:-null}" = null ]; then 
    echo "not running" 
else 
    echo "running" 
fi 
+0

我试过了,也不行。我的环境一定有些可疑(共享主机提供商)。 – elasticsecurity 2010-05-25 10:00:20

+0

尝试使用#!/ bin/sh -x来查看执行过程? – Anders 2010-05-25 10:03:49

+0

没有什么特别的:输出是 + SERVICE =导轨 + PS -a +的grep -v grep的 + grep的导轨 +导致= 1 +回波 '退出代码:1' 退出代码:1 +' ''1 -eq 0']' ++ date + echo'Tue May 25 06:52:25 EDT 2010:rails is not running' – elasticsecurity 2010-05-25 10:53:14

1

我发现了这个问题。 ps -ae改为ps -a的作品。

我想这与我在共享主机环境中的权利有关。从命令行执行“ps -a”和在bash脚本中执行它之间显然有区别。

4

工作一。

 
!/bin/bash 
CHECK=$0 
SERVICE=$1 
DATE=`date` 
OUTPUT=$(ps aux | grep -v grep | grep -v $CHECK |grep $1) 
echo $OUTPUT 
if [ "${#OUTPUT}" -gt 0 ] ; 
then echo "$DATE: $SERVICE service running, everything is fine" 
else echo "$DATE: $SERVICE is not running" 
fi 
+0

pgrep是一个更好的解决方案,你仍然有问题,你不检查进程名称,但ps aux的整个输出。 – karsten 2018-01-12 12:02:13

3
 
#!/bin/bash 
ps axho comm| grep $1 > /dev/null 
result=$? 
echo "exit code: ${result}" 
if [ "${result}" -eq "0" ] ; then 
echo "`date`: $SERVICE service running, everything is fine" 
else 
echo "`date`: $SERVICE is not running" 
/etc/init.d/$1 restart 
fi 

像这样的事情

90

有几个非常简单的方法:

pgrep procname && echo Running 
pgrep procname || echo Not running 
killall -q -0 procname && echo Running 
pidof procname && echo Running 
+0

我怎样才能做到这一点,但没有从pgrep输出到控制台的PID? – Kostanos 2013-08-06 19:21:38

+5

使用''pgrep procname>/dev/null && echo Running'来避免pgrep输出PID – Kostanos 2013-08-06 19:27:50

+1

“killall -q”不会说一个字 – Andor 2013-09-27 14:05:50

4

检查你的脚本名称不包含$服务。如果确实如此,它将以ps结果显示,导致脚本始终认为该服务正在运行。你可以像这样用当前文件名grep它:

#!/bin/sh 
SERVICE=$1 
if ps ax | grep -v grep | grep -v $0 | grep $SERVICE > /dev/null 
then 
    echo "$SERVICE service running, everything is fine" 
else 
    echo "$SERVICE is not running" 
fi 
+1

对于那些希望将其用作脚本的一部分,而不是作为函数,将$ 0更改为grep 'ps ax | grep -v grep | grep -v grep | grep $ SERVICE>/dev/null' – NullVoxPopuli 2013-07-09 13:34:34

2

这些是有用的提示。我只需要知道在启动脚本时服务是否正在运行,因此当我离开时我可以将服务保持在同一状态。最后我用这样的:

HTTPDSERVICE=$(ps -A | grep httpd | head -1) 

    [ -z "$HTTPDSERVICE" ] && echo "No apache service running." 
8

我用这个来检查每10秒进程正在运行,如果没有启动,并允许多个参数:

#!/bin/sh 

PROCESS="$1" 
PROCANDARGS=$* 

while : 
do 
    RESULT=`pgrep ${PROCESS}` 

    if [ "${RESULT:-null}" = null ]; then 
      echo "${PROCESS} not running, starting "$PROCANDARGS 
      $PROCANDARGS & 
    else 
      echo "running" 
    fi 
    sleep 10 
done  
1

安道尔的上述之一的一个简单的脚本版本建议:

!/bin/bash 

pgrep $1 && echo Running 

如果上面的脚本名为test.sh然后,为了试验,型式: test.sh NameOfProcessToCheck

例如 test.sh php

6

这个技巧适用于我。希望这可以帮助你。让我们将以下保存为checkRunningProcess.sh

#!/bin/bash 
ps_out=`ps -ef | grep $1 | grep -v 'grep' | grep -v $0` 
result=$(echo $ps_out | grep "$1") 
if [[ "$result" != "" ]];then 
    echo "Running" 
else 
    echo "Not Running" 
fi 

充分利用checkRunningProcess.sh executable.And然后使用它。
使用示例。

20:10 $ checkRunningProcess.sh proxy.py 
Running 
20:12 $ checkRunningProcess.sh abcdef 
Not Running 
0

我在想,如果这将是有进步的企图的过程是一个好主意,让你通过这个FUNC进程名称func_terminate_process“火狐”,它的轮胎东西更漂亮,然后再转移到杀。

# -- NICE: try to use killall to stop process(s) 
killall ${1} > /dev/null 2>&1 ;sleep 10 

# -- if we do not see the process, just end the function 
pgrep ${1} > /dev/null 2>&1 || return 

# -- UGLY: Step trough every pid and use kill -9 on them individually 
for PID in $(pidof ${1}) ;do 

    echo "Terminating Process: [${1}], PID [${PID}]" 
    kill -9 ${PID} ;sleep 10 

    # -- NASTY: If kill -9 fails, try SIGTERM on PID 
    if ps -p ${PID} > /dev/null ;then 
     echo "${PID} is still running, forcefully terminating with SIGTERM" 
     kill -SIGTERM ${PID} ;sleep 10 
    fi 

done 

# -- If after all that, we still see the process, report that to the screen. 
pgrep ${1} > /dev/null 2>&1 && echo "Error, unable to terminate all or any of [${1}]" || echo "Terminate process [${1}] : SUCCESSFUL" 
4

尽管在bash中/ dev/null方法取得了一些成功。当我将解决方案推向cron时,它失败了。虽然检查返回的命令的大小工作完美。 ampersrand允许bash退出。

#!/bin/bash 
SERVICE=/path/to/my/service 
result=$(ps ax|grep -v grep|grep $SERVICE) 
echo ${#result} 
if ${#result}> 0 
then 
     echo " Working!" 
else 
     echo "Not Working.....Restarting" 
     /usr/bin/xvfb-run -a /opt/python27/bin/python2.7 SERVICE & 
fi 
-1

最简单的检查,按进程名:

bash -c 'checkproc ssh.exe ; while [ $? -eq 0 ] ; do echo "proc running";sleep 10; checkproc ssh.exe; done' 
+0

这看起来像一个Windows解决方案,而不是一个很好的解决方案。你能链接到'checkproc'的文档吗? – tripleee 2017-10-31 05:15:03

0

我需要从时间做到这一点时间,并最终黑客命令行,直到它的工作原理。

例如,在这里我想看看我是否有任何SSH连接(由“PS”返回第八栏是运行“路径到PROCNAME”,并通过“AWK”过滤:

ps | awk -e '{ print $8 }' | grep ssh | sed -e 's/.*\///g' 

然后我把它放在一个外壳脚本,(“EVAL” -ing反引号内的命令行),这样的:

#!/bin/bash 

VNC_STRING=`ps | awk -e '{ print $8 }' | grep vnc | sed -e 's/.*\///g'` 

if [ ! -z "$VNC_STRING" ]; then 
    echo "The VNC STRING is not empty, therefore your process is running." 
fi 

的“sed的”部分修剪的确切令牌的路径和可能并不需要您的需求。

这是我用来获得答案的示例。我写它自动创建2个SSH隧道并为每个客户端启动一个VNC客户端。我也可以用一个命令跳到UNIX/LINUX-land(这也假定客户端的rsa键已经是“ssh-key”), copy-id“-ed并且对远程主机是已知的)。

它的幂等性在于每个proc /命令仅在其$ VAR eval为空字符串时触发。

它附加“| wc -l”来存储匹配的正在运行的proc的数量(即找到的行数),而不是每个$ VAR的proc-name以满足我的需要。我保留“回声”语句,以便我可以重新运行并诊断两个连接的状态。

#!/bin/bash 

SSH_COUNT=`eval ps | awk -e '{ print $8 }' | grep ssh | sed -e 's/.*\///g' | wc -l` 
VNC_COUNT=`eval ps | awk -e '{ print $8 }' | grep vnc | sed -e 's/.*\///g' | wc -l` 

if [ $SSH_COUNT = "2" ]; then 
    echo "There are already 2 SSH tunnels." 
elif [ $SSH_COUNT = "1" ]; then 
    echo "There is only 1 SSH tunnel." 
elif [ $SSH_COUNT = "0" ]; then 
    echo "connecting 2 SSH tunnels." 
    ssh -L 5901:localhost:5901 -f -l USER1 HOST1 sleep 10; 
    ssh -L 5904:localhost:5904 -f -l USER2 HOST2 sleep 10; 
fi 

if [ $VNC_COUNT = "2" ]; then 
    echo "There are already 2 VNC sessions." 
elif [ $VNC_COUNT = "1" ]; then 
    echo "There is only 1 VNC session." 
elif [ $VNC_COUNT = "0" ]; then 
    echo "launching 2 vnc sessions." 
    vncviewer.exe localhost:1 & 
    vncviewer.exe localhost:4 & 
fi 

这对我来说很像perl-like,可能比真正的shell脚本更多的是unix utils。我知道有很多“MAGIC”数字和cheezy硬编码的价值,但它的工作原理,(我认为我也使用这么多大写字母的口味不佳)。灵活性可以添加一些CMD线参数,使这更多功能,但我想分享什么对我有用。请改善和分享。干杯。

0

一个包含serviceawk的解决方案,它包含逗号分隔的服务名称列表。

首先,它可能是一个很好的选择,你需要root权限才能做你想做的事情。如果你不需要检查,那么你可以删除该部分。

#!/usr/bin/env bash 

# First parameter is a comma-delimited string of service names i.e. service1,service2,service3 
SERVICES=$1 

ALL_SERVICES_STARTED=true 

if [ $EUID -ne 0 ]; then 
    if [ "$(id -u)" != "0" ]; then 
    echo "root privileges are required" 1>&2 
    exit 1 
    fi 
    exit 1 
fi 

for service in ${SERVICES//,/ } 
do 
    STATUS=$(service ${service} status | awk '{print $2}') 

    if [ "${STATUS}" != "started" ]; then 
     echo "${service} not started" 
     ALL_SERVICES_STARTED=false 
    fi 
done 

if ${ALL_SERVICES_STARTED} ; then 
    echo "All services started" 
    exit 0 
else 
    echo "Check Failed" 
    exit 1 
fi