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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9117507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:20:20  来源:igfitidea点击:

Linux/Unix command to determine if process is running?

linuxbashshellunixprocess

提问by Highway of Life

I need a platform independent (Linux/Unix|OSX) shell/bash command that will determine if a specific process is running. e.g. mysqld, httpd... What is the simplest way/command to do this?

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

采纳答案by Caleb Gray

While pidofand pgrepare great tools for determining what's running, they are both, unfortunately, unavailable on some operating systems. A definite fail safe would be to use the following: ps cax | grep command

虽然pidofpgrep是确定正在运行什么的好工具,但不幸的是,它们在某些操作系统上都不可用。一个明确的故障安全将使用以下内容:ps cax | grep command

The output on Gentoo Linux:

Gentoo Linux 上的输出:

14484 ?        S      0:00 apache2
14667 ?        S      0:00 apache2
19620 ?        Sl     0:00 apache2
21132 ?        Ss     0:04 apache2

The output on OS X:

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)

On both Linux and OS X, grep returns an exit code so it's easy to check if the process was found or not:

在 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


Furthermore, if you would like the list of PIDs, you could easily grep for those as well:

此外,如果您想要 PID 列表,您也可以轻松地 grep 获取这些列表:

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

Whose output is the same on Linux and OS X:

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

3519 3521 3523 3524

The output of the following is an empty string, making this approach safe for processes that are not running:

以下输出是一个空字符串,使这种方法对于未运行的进程是安全的:

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

This approach is suitable for writing a simple empty string test, then even iterating through the discovered PIDs.

这种方法适用于编写一个简单的空字符串测试,然后甚至遍历发现的 PID。

#!/bin/bash
PROCESS=
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

You can test it by saving it to a file (named "running") with execute permissions (chmod +x running) and executing it with a parameter: ./running "httpd"

您可以通过将其保存到具有执行权限(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


WARNING!!!

警告!!!

Please keep in mind that you're simply parsing the output of ps axwhich means that, as seen in the Linux output, it is not simply matching on processes, but also the arguments passed to that program. I highly recommend being as specific as possible when using this method (e.g. ./running "mysql"will also match 'mysqld' processes). I highly recommend using whichto check against a full path where possible.

请记住,您只是在解析其输出,ps ax这意味着,正如在 Linux 输出中所见,它不仅匹配进程,还匹配传递给该程序的参数。我强烈建议在使用此方法时尽可能具体(例如,./running "mysql"还将匹配 'mysqld' 进程)。我强烈建议which在可能的情况下使用来检查完整路径。



References:

参考:

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

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

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

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

回答by Frédéric Hamidi

On most Linux distributions, you can use pidof(8).

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

It will print the process ids of all running instances of specified processes, or nothing if there are no instances running.

它将打印指定进程的所有正在运行的实例的进程 ID,如果没有实例在运行,则不打印。

For instance, on my system (I have four instances of bashand one instance of remminarunning):

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

$ pidof bash remmina
6148 6147 6144 5603 21598

On other Unices, pgrepor a combination of psand grepwill achieve the same thing, as others have rightfully pointed out.

在其它UNIX系统中,pgrep或组合ps,并grep会取得同样的事情,正如其他人理所当然地指出。

回答by olibre

I use pgrep -l httpdbut not sure it is present on any platform...
Who can confirm on OSX?

我使用pgrep -l httpd但不确定它是否存在于任何平台上...
谁能在 OSX 上确认?

回答by Johnsyweb

This should work on most flavours of Unix, BSD and Linux:

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

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

Tested on:

测试:

  • SunOS 5.10 [Hence the PATH=...]
  • Linux 2.6.32 (CentOS)
  • Linux 3.0.0 (Ubuntu)
  • Darwin 11.2.0
  • FreeBSD 9.0-STABLE
  • Red Hat Enterprise Linux ES release 4
  • Red Hat Enterprise Linux Server release 5
  • SunOS 5.10 [因此PATH=...]
  • Linux 2.6.32 (CentOS)
  • Linux 3.0.0 (Ubuntu)
  • 达尔文 11.2.0
  • FreeBSD 9.0 稳定版
  • 红帽企业 Linux ES 第 4 版
  • 红帽企业 Linux 服务器第 5 版

回答by Tatjana Heuser

Just a minor addition: if you add the -cflag to ps, you don't need to remove the line containing the grep process with grep -vafterwards. I.e.

只是一个小补充:如果将-c标志添加到 ps,则无需删除包含 grep 进程的行grep -v。IE

ps acux | grep cron

is all the typing you'll need on a bsd-ish system (this includes MacOSX) You can leave the -uaway if you need less information.

是您在 bsd-ish 系统(包括 MacOSX)上需要的所有输入-u,如果您需要较少的信息,您可以离开。

On a system where the genetics of the native pscommand point back to SysV, you'd use

在本机ps命令的遗传学指向 SysV 的系统上,您将使用

ps -e |grep cron

or

或者

ps -el |grep cron 

for a listing containing more than just pid and process name. Of course you could select the specific fields to print out using the -o <field,field,...>option.

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

回答by Pawel Solarski

The simpliest way is to use ps and 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

If your command has some command arguments, then you can also put more 'grep cmd_arg1' after 'grep $command' to filter out other possible processes that you are not interested in.

如果你的命令有一些命令参数,那么你也可以在 'grep $command' 后面放更多的 'grep cmd_arg1' 来过滤掉你不感兴趣的其他可能的进程。

Example: show me if any java process with supplied argument:

示例:如果有任何带有提供参数的 java 进程,请告诉我:

-Djava.util.logging.config.file=logging.properties

-Djava.util.logging.config.file=logging.properties

is running

在跑

ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l

回答by peterh

You SHOULD know the PID !

你应该知道PID!

Finding a process by trying to do some kind of pattern recognition on the process arguments (like pgrep "mysqld") is a strategy that is doomed to fail sooner or later. What if you have two mysqld running? Forget that approach. You MAY get it right temporarily and it MAY work for a year or two but then something happens that you haven't thought about.

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

Only the process id (pid) is truly unique.

只有进程 ID (pid) 才是真正唯一的。

Always store the pid when you launch something in the background. In Bash this can be done with the $!Bash variable. You will save yourself SO much trouble by doing so.

当您在后台启动某些东西时,请始终存储 pid。在 Bash 中,这可以通过$!Bash 变量来完成。这样做你会省去很多麻烦。

How to determine if process is running (by pid)

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

So now the question becomes how to know if a pid is running.

所以现在问题变成了如何知道 pid 是否正在运行。

Simply do:

简单地做:

ps -o pid= -p <pid>

This is POSIX and hence portable. It will return the pid itself if the process is running or return nothing if the process is not running. Strictly speaking the command will return a single column, the pid, but since we've given that an empty title header (the stuff immediately preceding the equals sign) and this is the only column requested then the ps command will not use header at all. Which is what we want because it makes parsing easier.

这是 POSIX,因此是可移植的。如果进程正在运行,它将返回 pid 本身,如果进程没有运行,它将不返回任何内容。严格地说,该命令将返回一个列, the pid,但由于我们已经给出了一个空的标题标题(等号前面的内容)并且这是唯一请求的列,那么 ps 命令将根本不使用标题。这就是我们想要的,因为它使解析更容易。

This will work on Linux, BSD, Solaris, etc.

这将适用于 Linux、BSD、Solaris 等。

Another strategy would be to test on the exit value from the above pscommand. It should be zero if the process is running and non-zero if it isn't. The POSIX spec says that psmust exit >0 if an error has occurred but it is unclear to me what constitutes 'an error'. Therefore I'm not personally using that strategy although I'm pretty sure it will work as well on all Unix/Linux platforms.

另一种策略是测试上述ps命令的退出值。如果进程正在运行,它应该是零,如果不是,它应该是非零。POSIX 规范说,ps如果发生错误,则必须退出 >0,但我不清楚什么构成“错误”。因此,虽然我很确定它在所有 Unix/Linux 平台上也能正常工作,但我个人并未使用该策略。

回答by Tom Lime

This approach can be used in case commands 'ps', 'pidof' and rest are not available. I personally use procfs very frequently in my tools/scripts/programs.

这种方法可用于命令“ps”、“pidof”和rest不可用的情况。我个人在我的工具/脚本/程序中非常频繁地使用 procfs。

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

Little explanation what is going on:

很少解释发生了什么:

  1. -m1 - stop process on first match
  2. "mysqld$|httpd$" - grep will match lines which ended on mysqld OR httpd
  3. /proc/[0-9]* - bash will match line which started with any number
  4. cut - just split the output by delimiter '/' and extract field 3
  1. -m1 - 在第一场比赛中停止进程
  2. "mysqld$|httpd$" - grep 将匹配以 mysqld 或 httpd 结尾的行
  3. /proc/[0-9]* - bash 将匹配以任何数字开头的行
  4. cut - 只需通过分隔符“/”分割输出并提取字段 3

回答by jlliagre

The following shell function, being only based on POSIX standard commands and options should work on most (if not any) Unix and linux system. :

以下 shell 函数仅基于 POSIX 标准命令和选项,应该适用于大多数(如果没有)Unix 和 linux 系统。:

isPidRunning() {
  cmd=`
    PATH=\`getconf PATH\` export PATH
    ps -e -o pid= -o comm= |
      awk ' ~ "^.*/'""'$" ||  ~ "^'""'$" {print ,}'
  `
  [ -n "$cmd" ] &&
    printf "%s is running\n%s\n\n" "" "$cmd" ||
    printf "%s is not running\n\n" 
  [ -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

Note that it will choke when passed the dubious "0]" command name and will also fail to identify processes having an embedded space in their names.

请注意,当传递可疑的“0]”命令名称时,它会窒息,并且也无法识别名称中包含嵌入空格的进程。

Note too that the most upvoted and accepted solution demands non portable psoptions and gratuitously uses a shell that is, despite its popularity, not guaranteed to be present on every Unix/Linux machine (bash)

还要注意,最受好评和接受的解决方案需要不可移植的ps选项,并且无缘无故地使用一个 shell,尽管它很受欢迎,但不能保证在每台 Unix/Linux 机器上都存在 ( bash)

回答by gletscher

Putting the various suggestions together, the cleanest version I was able to come up with (without unreliable grep which triggers parts of words) is:

将各种建议放在一起,我能想出的最干净的版本(没有不可靠的 grep 会触发部分单词)是:

kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

kill -0 doesn't kill the process but checks if it exists and then returns true, if you don't have pidof on your system, store the pid when you launch the process:

kill -0 不会终止进程,但会检查它是否存在,然后返回 true,如果您的系统上没有 pidof,请在启动进程时存储 pid:

$ mysql &
$ echo $! > pid_stored

then in the script:

然后在脚本中:

kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"