我需要一个跨平台的(Linux/Unix|OSX)shell/bash命令,用于确定特定进程是否正在运行。例如:mysqld
,httpd
...
最简单的方法/命令是什么?
虽然 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
此外,如果你想要进程ID列表,也可以很容易地使用grep实现:
ps cax | grep httpd | grep -o '^[ ]*[0-9]*'
这个命令在Linux和OS X上都可以使用:
3519 3521 3523 3524
下面的命令输出空字符串,因此对于没有运行的进程使用这种方法是安全的:
echo ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'
这种方法适合编写一个简单的空字符串测试,然后遍历发现的进程ID。
#!/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”)并使用参数执行它来测试它:./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
检查完整路径。
参考资料:
尝试对进程参数进行某种模式识别(例如 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平台上也可以很好地工作。
在大多数Linux发行版中,你可以使用pidof
(8)命令。
它会列出所有正在运行的指定进程的进程ID,如果没有正在运行的实例,则不会列出任何内容。
例如,在我的系统上(我有四个bash
实例和一个remmina
实例正在运行):
$ pidof bash remmina
6148 6147 6144 5603 21598
在其他Unix系统上,正如其他人所指出的那样,pgrep
或者ps
和grep
的组合也可以实现相同的功能。
PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep
测试环境:
PATH=...
]ps
命令即可。为了避免第二个 grep
,我建议使用:ps aux | grep [h]ttpd
。 - oHogrep
中。 - johnsyweb最简单的方法是使用 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
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"
。 - Highway of Liferunning
更改为 $running
,您将会收到以下错误信息 [: running: integer expression expected]
。 - nextloop将各种建议结合起来,我能想到的最干净的版本(不使用不可靠的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"
只需要做一个小改动:如果你在 ps 命令中添加 -c
标志,就不需要再使用 grep -v
命令删除包含 grep 进程的行了。例如:
ps acux | grep cron
如果您在使用类似BSD系统(包括MacOSX)的操作系统,那么 -u
参数就足够了,如果您不需要太多信息可以省略该参数。
如果您使用的是原生 ps
命令遵循 SysV 遗传特征的系统,则应使用以下命令:
ps -e |grep cron
或者
ps -el |grep cron
如果需要列出包含进程id和进程名称以外的更多信息,可以使用-o <field,field,...>
选项选择要打印出的具体字段。
我使用 pgrep -l httpd
,但不确定它是否存在于任何平台上...
有谁能在OSX上确认一下吗?
pidof
吗?好的,你已经检查了。谢谢。所以我们应该找到其他在OSX上工作的东西...你的基本ps|grep
可能是唯一的解决方案;-) - oHo没有一个答案对我有用,这是我的解决方案:
process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
echo "Process is not running."
else
echo "Process is running."
fi
解释:
|tr -d '\n'
这将删除终端创建的回车符。其余内容可以通过this文章解释。
egrep -m1 "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3
简要解释:
grep
命令会包含自身运行的进程(例如,ps cax | grep randomname
命令总是返回 0 ,因为grep
命令会找到grep randomname
的进程(希望这一点很清楚...)。一种解决方法是在进程名称的第一个字母周围添加方括号,例如ps cax | grep [r]andomname
命令。 - Kyle G.ps cax
可能无法完整输出命令名称。例如,它会打印出 "chromium-browse" 而不是 "chromium-browser"。 - jarnops cax | grep randomname
grep 不总是会返回0,但是ps ax | grep randomname
会。 - jarno