用于检查运行进程的Bash脚本

时间:2010-05-25 09:17:58

标签: bash

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

#!/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

Bash版本:GNU bash,版本3.2.25(1)-release(x86_64-redhat-linux-gnu)

15 个答案:

答案 0 :(得分:98)

有一些非常简单的方法:

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

答案 1 :(得分:14)

在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

答案 2 :(得分:10)

这个技巧对我有用。希望这可以帮到你。让我们将以下内容保存为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可执行。然后使用它。
使用示例。

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

答案 3 :(得分:9)

我使用这个来检查每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    

答案 4 :(得分:6)

检查您的脚本名称是否包含$ SERVICE。如果是,它将在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

答案 5 :(得分:5)

工作一个。

!/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

答案 6 :(得分:5)

尽管在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

答案 7 :(得分:4)

#!/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

像这样的东西

答案 8 :(得分:3)

这些都是有用的提示。我只需要知道当我启动脚本时服务是否正在运行,所以当我离开时我可以将服务保持在相同的状态。我最终使用了这个:

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

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

答案 9 :(得分:2)

我发现了问题。 ps -ae而不是ps -a可以工作。

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

答案 10 :(得分:2)

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

!/bin/bash

pgrep $1 && echo Running

如果上面的脚本名为test.sh,那么为了测试,输入: test.sh NameOfProcessToCheck

e.g。 test.sh php

答案 11 :(得分:1)

我想知道在进程中进行渐进式尝试是否是一个好主意,所以你将这个函数传递给进程名称func_terminate_process“firefox”,它首先使事情变得更好,然后继续杀死。

# -- 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"

答案 12 :(得分:1)

我需要不时地执行此操作并最终破解命令行直到它工作。

例如,在这里,我想看看我是否有任何SSH连接,(&#34返回的第8列; ps"正在运行"路径到procname"并且已过滤通过" awk":

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

然后我把它放在一个shell脚本中,(" eval" - 在反引号内部的命令行),像这样:

#!/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" part修剪了确切令牌的路径,可能不是您需要的。

以下是我用来得到答案的例子。我写它是为了自动创建2个SSH隧道并为每个隧道启动一个VNC客户端。

我从我的Cygwin shell运行它来从我的Windows工作站对我的后端进行管理,所以我可以用一个命令跳转到UNIX / LINUX-land(这也假设客户端rsa键已经是" ssh-copy-id" -ed并为远程主机所知。

它是幂等的,每个proc /命令只在$ VAR eval为空字符串时才会触发。

它追加" | wc -l"存储匹配的运行过程的数量(即,找到的行数),而不是每个$ 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

这对我来说非常类似,并且可能比真正的shell脚本更多的unix工具。我知道有很多" MAGIC"数字和cheezy硬编码值,但它的工作原理,(我认为我也很不喜欢使用这么多的大写)。可以使用一些cmd-line args添加灵活性,以使其更加通用,但我想分享对我有用的东西。请改进和分享。欢呼声。

答案 13 :(得分:1)

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

答案 14 :(得分:-1)

按进程名称进行最简单的检查:

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