Answers:
虽然pidof
和pgrep
是确定正在运行的工具,但遗憾的是,它们在某些操作系统上均不可用。绝对的故障保护将使用以下内容:ps cax | grep command
Gentoo Linux上的输出:
14484?S 0:00 apache2 14667吗?S 0:00 apache2 19620?SL 0:00 apache2 21132?SS 0:04 apache2
OS X上的输出:
42582 ?? Z 0:00.00(smbclient) 46529 ?? Z 0:00.00(smbclient) 46539 ?? Z 0:00.00(smbclient) 46547 ?? Z 0:00.00(smbclient) 46586 ?? Z 0:00.00(smbclient) 46594 ?? Z 0:00.00(smbclient)
在Linux和OS X上,grep都会返回退出代码,因此很容易检查是否找到了该进程:
#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
echo "Process is running."
else
echo "Process is not running."
fi
此外,如果您想要PID的列表,也可以轻松地对这些ID进行grep:
ps cax | grep httpd | grep -o'^ [] * [0-9] *'
在Linux和OS X上谁的输出是相同的:
3519 3521 3523 3524
以下内容的输出为空字符串,从而使该方法对于未运行的进程而言是安全的:
回声 ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'
这种方法适用于编写简单的空字符串测试,然后甚至遍历发现的PID。
#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
echo "Process not running." 1>&2
exit 1
else
for PID in $PIDS; do
echo $PID
done
fi
您可以通过将其保存到具有执行权限(chmod + x running)的文件(名为“ running”)并使用参数执行该文件来对其进行测试: ./running "httpd"
#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
echo "Process is running."
else
echo "Process is not running."
fi
警告!!!
请记住,您只是在解析输出,ps ax
这意味着从Linux输出中可以看出,它不仅与进程匹配,而且还传递给该程序的参数。我强烈建议在使用此方法时尽可能具体(例如./running "mysql"
也将匹配“ mysqld”进程)。我强烈建议which
在可能的情况下使用来检查完整路径。
参考文献:
grep
也将发现自己运行(例如ps cax | grep randomname
将始终返回0,因为grep
出土文物grep randomname
(希望这是明确的...)一个解决方法是添加周围的进程名的第一个字母,例如方括号。ps cax | grep [r]andomname
。
ps cax | rev | cut -f1 -d' ' | rev
将仅显示名称列,以便于解析。
ps cax
可能不会完全输出命令名称。例如,它打印“铬浏览器”而不是“铬浏览器”。
通过尝试对流程参数(例如pgrep "mysqld"
)进行某种模式识别来查找流程是一种注定迟早会失败的策略。如果您有两个mysqld正在运行怎么办?忘记这种方法。您可以暂时正确使用它,并且可以工作一两年,但是随后发生了一些您未曾想到的事情。
只有进程ID(pid)才是真正唯一的。
在后台启动某些东西时,请始终存储该pid。在Bash中,可以使用$!
Bash变量来完成。这样可以为您省下很多麻烦。
所以现在的问题变成了如何知道pid是否正在运行。
只需做:
ps -o pid = -p <pid>
这是POSIX,因此可移植。如果进程正在运行,它将返回pid本身;如果进程未运行,则将不返回任何值。严格来说,该命令将返回单个列,pid
但由于我们给出了一个空的标题标头(等号前面的内容),并且这是所请求的唯一列,因此ps命令将根本不使用标头。这就是我们想要的,因为它使解析更加容易。
这将适用于Linux,BSD,Solaris等。
另一种策略是测试以上ps
命令的退出值。如果进程正在运行,则应为零;如果未运行,则应为非零。POSIX规范指出,ps
如果发生错误,则必须退出> 0,但我不清楚什么构成“错误”。因此,尽管我非常确定它可以在所有Unix / Linux平台上正常工作,但我个人并没有使用该策略。
grep <sometext>
来找到给定的流程,那么在启动该流程时,您做错了什么,恕我直言。我从OP的问题中得出的结论是,他确实控制了流程的启动方式。
在大多数Linux发行版中,您可以使用pidof
(8)。
它将打印指定进程的所有正在运行实例的进程ID,如果没有实例在运行,则不打印任何内容。
例如,在我的系统上(我有四个实例,bash
一个remmina
正在运行):
$ pidof bash remmina
6148 6147 6144 5603 21598
在其它UNIX系统中,pgrep
或组合ps
,并grep
会取得同样的事情,正如其他人理所当然地指出。
pidof httpd
在Red Hat 5上工作正常。但是在我的Red Hat 4 pidof
上却不存在:-(
这应该适用于大多数Unix,BSD和Linux版本:
PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep
经过测试:
PATH=...
]ps
。为了避免第二个,grep
我建议:ps aux | grep [h]ttpd
grep
。
最简单的方法是使用ps和grep:
command="httpd"
running=`ps ax | grep -v grep | grep $command | wc -l`
if [ running -gt 0 ]; then
echo "Command is running"
else
echo "Command is not running"
fi
如果您的命令包含一些命令参数,那么您也可以在'grep $ command'之后放置更多的'grep cmd_arg1',以过滤掉您不感兴趣的其他可能进程。
示例:告诉我是否有带有提供的参数的java进程:
-Djava.util.logging.config.file = logging.properties
在跑
ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l
ps cax
消除了使用的需要grep -v
。因此,例如,您可以使用:ps cax | grep java > /dev/null || echo "Java not running"
。
只是一个小小的补充:如果您将-c
标志添加到ps,则无需grep -v
随后删除包含grep进程的行。即
ps acux | grep cron
是在bsd-ish系统(包括MacOSX)上需要的所有输入内容-u
,如果您需要的信息较少,可以省去一切。
在本机ps
命令遗传指向SysV的系统上,您将使用
ps -e |grep cron
要么
ps -el |grep cron
对于包含不仅仅是pid和进程名称的列表。当然,您可以使用-o <field,field,...>
选项选择要打印的特定字段。
综合各种建议,我能想到的最简洁的版本(没有不可靠的grep会触发单词的一部分)是:
kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"
kill -0不会杀死进程,但会检查进程是否存在,然后返回true,如果您的系统上没有pidof,请在启动进程时存储pid:
$ mysql &
$ echo $! > pid_stored
然后在脚本中:
kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"
我使用pgrep -l httpd
但不确定在任何平台上都存在...
谁可以在OSX上进行确认?
pidof
一下吗?好,你做到了。谢谢。因此,我们应该在OSX上找到其他工作方式……您的基本方法ps|grep
可能是单一解决方案;-)
启动它时,其PID将记录在$!
变量中。将此PID保存到文件中。
然后,您将需要检查此PID是否对应于正在运行的进程。这是一个完整的框架脚本:
FILE="/tmp/myapp.pid"
if [ -f $FILE ];
then
PID=$(cat $FILE)
else
PID=1
fi
ps -o pid= -p $PID
if [ $? -eq 0 ]; then
echo "Process already running."
else
echo "Starting process."
run_my_app &
echo $! > $FILE
fi
基于该回答的peterh
。知道给定PID是否正在运行的诀窍在ps -o pid= -p $PID
指令中。
这将打印基本名称为“ chromium-browser”的进程数:
ps -e -o args= | awk 'BEGIN{c=0}{
if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets.
if($1==cmd){c++}
}END{print c}' cmd="chromium-browser"
如果显示“ 0”,则表明该进程未运行。该命令假定进程路径不包含空格。我尚未使用暂停进程或僵尸进程对此进行测试。
在Linux上gwak
用作awk
替代测试。
这是一个更加通用的解决方案,并带有一些示例用法:
#!/bin/sh
isProcessRunning() {
if [ "${1-}" = "-q" ]; then
local quiet=1;
shift
else
local quiet=0;
fi
ps -e -o pid,args= | awk 'BEGIN{status=1}{
name=$2
if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets.
if(name==cmd){status=0; if(q){exit}else{print $0}}
}END{exit status}' cmd="$1" q=$quiet
}
process='chromium-browser'
printf "Process \"${process}\" is "
if isProcessRunning -q "$process"
then printf "running.\n"
else printf "not running.\n"; fi
printf "Listing of matching processes (PID and process name with command line arguments):\n"
isProcessRunning "$process"
这是我的版本。特征:
脚本:
#!/bin/bash
# $1 - cmd
# $2 - args
# return: 0 - no error, running; 1 - error, not running
function isRunning() {
for i in $(pidof $1); do
cat /proc/$i/cmdline | tr '\000' ' ' | grep -F -e "$2" 1>&2> /dev/null
if [ $? -eq 0 ]; then
return 0
fi
done
return 1
}
isRunning java "-Djava.util.logging.config.file=logging.properties"
if [ $? -ne 0 ]; then
echo "not running, starting..."
fi
没有一个答案对我有用,所以这是我的:
process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
echo "Process is not running."
else
echo "Process is running."
fi
说明:
|tr -d '\n'
这将删除由终端创建的回车。其余的可以通过这篇文章解释。
以下仅基于POSIX标准命令和选项的shell函数应在大多数(如果没有)Unix和linux系统上运行。:
isPidRunning() {
cmd=`
PATH=\`getconf PATH\` export PATH
ps -e -o pid= -o comm= |
awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}'
`
[ -n "$cmd" ] &&
printf "%s is running\n%s\n\n" "$1" "$cmd" ||
printf "%s is not running\n\n" $1
[ -n "$cmd" ]
}
$ isPidRunning httpd
httpd is running
586 /usr/apache/bin/httpd
588 /usr/apache/bin/httpd
$ isPidRunning ksh
ksh is running
5230 ksh
$ isPidRunning bash
bash is not running
请注意,当传递可疑的“ 0]”命令名称时,它将阻塞,并且也将无法识别名称中包含空格的进程。
还要注意,最受支持和接受的解决方案需要非便携式ps
选项,并且无偿使用了一个外壳,尽管它很受欢迎,但并不能保证每个Unix / Linux机器上都存在该外壳(bash
)
$ isPidRunning 0]
打印,例如“ 0”正在运行3 [ksoftirqd / 0] 8 [rcuop / 0] 17 [rcuos / 0] 26 [rcuob / 0] 34 [migration / 0] 35 [watchdog / 0]”。