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
Linux/Unix command to determine if process is running?
提问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 命令来确定特定进程是否正在运行。例如mysqld
,httpd
...最简单的方法/命令是什么?
采纳答案by Caleb Gray
While pidof
and pgrep
are 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
虽然pidof
和pgrep
是确定正在运行什么的好工具,但不幸的是,它们在某些操作系统上都不可用。一个明确的故障安全将使用以下内容: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 ax
which 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 which
to 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
回答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 bash
and one instance of remmina
running):
例如,在我的系统上(我有四个运行实例bash
和一个remmina
运行实例):
$ pidof bash remmina
6148 6147 6144 5603 21598
On other Unices, pgrep
or a combination of ps
and grep
will achieve the same thing, as others have rightfully pointed out.
在其它UNIX系统中,pgrep
或组合ps
,并grep
会取得同样的事情,正如其他人理所当然地指出。
回答by olibre
I use pgrep -l httpd
but 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 -c
flag to ps, you don't need to remove the line containing the grep process with grep -v
afterwards. 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 -u
away if you need less information.
是您在 bsd-ish 系统(包括 MacOSX)上需要的所有输入-u
,如果您需要较少的信息,您可以离开。
On a system where the genetics of the native ps
command 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 ps
command. It should be zero if the process is running and non-zero if it isn't. The POSIX spec says that ps
must 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:
很少解释发生了什么:
- -m1 - stop process on first match
- "mysqld$|httpd$" - grep will match lines which ended on mysqld OR httpd
- /proc/[0-9]* - bash will match line which started with any number
- cut - just split the output by delimiter '/' and extract field 3
- -m1 - 在第一场比赛中停止进程
- "mysqld$|httpd$" - grep 将匹配以 mysqld 或 httpd 结尾的行
- /proc/[0-9]* - bash 将匹配以任何数字开头的行
- 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 ps
options 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"