Linux / Unix命令来确定进程是否正在运行?

我需要一个独立于平台的(Linux / Unix | OSX)shell / bash命令来确定特定进程是否正在运行。 例如mysqldhttpd …什么是最简单的方法/命令来做到这一点?

虽然pidofpgrep是确定正在运行的很好的工具,但是在某些操作系统上,它们都是不可用的。 一个确定的故障安全将是使用以下: ps cax | grep command 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都会返回一个退出代码,所以很容易检查是否find进程:

 #!/bin/bash ps cax | grep httpd > /dev/null if [ $? -eq 0 ]; then echo "Process is running." else echo "Process is not running." fi 

而且,如果你想要PID的列表,你也可以很容易地理解这些:

  ps cax |  grep httpd |  grep -o'^ [] * [0-9] *' 

在Linux和OS X上,其输出是相同的:

  3519 3521 3523 3524 

下面的输出是一个空string,使得这个方法对于没有运行的进程是安全的:

 回声ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*' ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*' 

这种方法适用于编写简单的空stringtesting,然后遍历发现的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 

您可以通过将其保存到具有执行许可权的文件(命名为“running”)(chmod + x running)并使用参数执行它进行testing: ./running "httpd"

 #!/bin/bash ps cax | grep httpd if [ $? -eq 0 ]; then echo "Process is running." else echo "Process is not running." fi 

警告!!!

请记住,您只是parsingps ax的输出,这意味着,如在Linux输出中所看到的,它不是简单地匹配进程,而是传递给该程序的参数。 我强烈build议使用这种方法尽可能具体(例如./running "mysql"也将匹配'mysqld'进程)。 我强烈build议在可能的情况下使用which检查完整path。


参考文献:

http://linux.about.com/od/commands/l/blcmdl1_ps.htm

http://linux.about.com/od/commands/l/blcmdl1_grep.htm

你应该知道PID!

通过尝试对进程参数(如pgrep "mysqld" )进行某种模式识别来寻找进程是一种注定迟早会失败的策略。 如果你有两个mysqld运行? 忘记这个办法。 你可能暂时得到它,它可能会工作一年或两年,但然后发生了一些事情,你没有想过。

只有进程ID(PID)是真正独特的。

当您在后台启动某些内容时,请始终存储该pid。 在Bash中,这可以用$!来完成 Bashvariables。 你这样做可以省去很多麻烦。

如何确定进程是否正在运行(通过pid)

所以现在问题变成如何知道一个PID是否正在运行。

简单地做:

 ps -o pid = -p <pid>

这是POSIX,因此是便携式的。 如果进程正在运行,它将返回pid本身,如果进程没有运行,它将返回任何内容。 严格地说,命令会返回一个单独的列,即pid ,但是由于我们已经给出了一个空的标题头(等号之前的东西),这是唯一请求的列,所以ps命令根本不会使用头。 这是我们想要的,因为它使parsing更容易。

这将在Linux,BSD,Solaris等上运行

另一个策略是testing上面ps命令的退出值。 如果进程正在运行,它应该是零,如果不是,则应该是非零。 POSIX规范说,如果出现错误, ps必须退出> 0,但是我不清楚什么是“错误”。 所以我不是亲自使用这个策略,虽然我很确定它在所有Unix / Linux平台上都能正常工作。

在大多数Linux发行版上,可以使用pidof (8)。

它将打印指定进程的所有正在运行的实例的进程标识符,如果没有实例正在运行,则不显示任何内容。

例如,在我的系统上(我有四个bash实例和一个remmina运行实例):

 $ pidof bash remmina 6148 6147 6144 5603 21598 

在其他Unices上, pgrep或者psgrep的组合可以达到同样的效果,正如其他人正确地指出的那样。

只是一个小的增加:如果你添加-c标志到ps,你不需要用grep -v去除包含grep进程的行。 即

 ps acux | grep cron 

是您在bsd-ish系统(包括MacOSX)上所需的全部input。如果您需要较less的信息,则可以将-u离开。

在本地ps命令的遗传学指向SysV的系统上,您可以使用

 ps -e |grep cron 

要么

 ps -el |grep cron 

对于包含不仅仅是pid和进程名称的列表。 当然,您可以使用-o <field,field,...>选项来select要打印的特定字段。

这应该适用于大多数Unix,BSD和Linux:

 PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep 

testing:

  • SunOS 5.10 [因此PATH=... ]
  • Linux 2.6.32(CentOS)
  • Linux 3.0.0(Ubuntu)
  • 达尔文11.2.0
  • FreeBSD 9.0-STABLE
  • 红帽企业Linux ES版本4
  • 红帽企业Linux服务器版本5

最简单的方法是使用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 

把各种各样的build议放在一起,我能够想到的最干净的版本(没有不可靠的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上确认?

你应该知道你的过程的PID。

当你启动它时,它的PID将被logging在$! variables。 将这个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指令中。

这种方法可用于命令'ps','pidof'和rest不可用的情况。 我个人在我的工具/脚本/程序中经常使用procfs。

  egrep -m1 "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3 

小解释发生了什么事情:

  1. -m1 – 第一场比赛停止进程
  2. “mysqld $ | httpd $” – grep将匹配以mysqld或httpd结尾的行
  3. / proc / [0-9] * – bash将匹配以任何数字开头的行
  4. 剪切 – 只是通过分隔符“/”分割输出,并提取字段3

这将打印基本名称为“铬浏览器”的进程数量:

 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”,进程不运行。 该命令假定进程path不包含中断空间。 我没有testing过这个暂停进程或僵尸进程。

在Linux中使用gwak作为awk替代方法进行testing。

以下是一些用途较为全面的解决scheme:

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

下面的shell函数,只是基于POSIX标准的命令和选项,应该在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”命令名称时它会窒息,并且也将无法识别其名称中具有embedded空间的进程。

还要注意,最有利的和被接受的解决scheme要求不可移植的ps选项,并无偿地使用一个shell,尽pipe它受欢迎,但不能保证在每个Unix / Linux机器( bash