我编写了一个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)
答案 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)
service
和awk
的解决方案,其中包含以逗号分隔的服务名称列表。
首先,你可能需要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'