Linux/Unix 命令确定进程是否正在运行?
- 2024-10-29 08:34:00
- admin 原创
- 50
问题描述:
我需要一个独立于平台的(Linux/Unix|OSX)shell/bash 命令来确定特定进程是否正在运行。例如mysqld
,httpd
... 执行此操作的最简单方法/命令是什么?
解决方案 1:
虽然pidof
和pgrep
都是确定正在运行什么的好工具,但不幸的是,它们在某些操作系统上都不可用。绝对安全的方法是使用以下命令:ps cax | grep command
Gentoo Linux 上的输出:
14484 ? S 0:00 apache2
14667 ? S 0:00 apache2
19620 ? 下午 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(SMB 客户端)
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 列表,您也可以轻松地 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
尽可能使用来检查完整路径。
参考:
http://linux.about.com/od/commands/l/blcmdl1_ps.htm
http://linux.about.com/od/commands/l/blcmdl1_grep.htm
解决方案 2:
您应该知道 PID!
通过尝试对进程参数(如)进行某种模式识别来查找进程pgrep "mysqld"
是一种注定迟早会失败的策略。如果您有两个 mysqld 正在运行怎么办?忘掉这种方法吧。您可能会暂时正确使用它,并且它可能可以工作一两年,但随后会发生一些您没有想到的事情。
只有进程 ID (pid) 是真正唯一的。
在后台启动某些程序时,请务必存储 pid。在 Bash 中,可以使用$!
Bash 变量来完成此操作。这样做可以为您省去很多麻烦。
如何判断进程是否正在运行(通过 pid)
所以现在的问题变成了如何知道 pid 是否正在运行。
只需这样做:
ps -o pid=-p <pid>
这是 POSIX,因此是可移植的。如果进程正在运行,它将返回 pid 本身;如果进程未运行,则不返回任何内容。严格来说,该命令将返回单个列,即pid
,但由于我们为其指定了一个空的标题 header(等号前面的内容),并且这是唯一请求的列,因此 ps 命令根本不会使用 header。这正是我们想要的,因为它使解析更容易。
这将适用于 Linux、BSD、Solaris 等。
另一种策略是测试上述ps
命令的退出值。如果进程正在运行,则退出值应为零,否则应为非零。POSIX 规范规定,ps
如果发生错误,则退出值必须大于 0,但我不清楚什么构成“错误”。因此,我个人不使用该策略,尽管我非常确定它在所有 Unix/Linux 平台上都能正常工作。
解决方案 3:
在大多数 Linux 发行版上,您可以使用pidof
(8)。
它将打印指定进程的所有正在运行的实例的进程 ID,如果没有正在运行的实例,则不打印任何内容。
例如,在我的系统上(我有四个实例bash
和一个remmina
正在运行的实例):
$ pidof bash remmina
6148 6147 6144 5603 21598
在其他 Unices 上,或者和pgrep
的组合将实现同样的效果,正如其他人正确指出的那样。ps
`grep`
解决方案 4:
这应该适用于大多数版本的 Unix、BSD 和 Linux:
PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep
已测试:
SunOS 5.10 [因此
PATH=...
]Linux 2.6.32(CentOS)
Linux 3.0.0(Ubuntu)
达尔文 11.2.0
FreeBSD 9.0-稳定版
Red Hat Enterprise Linux ES 版本 4
Red Hat Enterprise Linux 服务器版本 5
解决方案 5:
综合考虑各种建议,我能想到的最干净的版本(没有触发部分单词的不可靠 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"
解决方案 6:
最简单的方法是使用 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.文件=logging.properties
正在运行
ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l
解决方案 7:
只是一点小小的补充:如果你将-c
标志添加到 ps,则无需删除包含 grep 进程的行grep -v
。即
ps acux | grep cron
是您在 bsd-ish 系统 (包括 MacOSX) 上需要的所有输入,-u
如果您需要较少的信息,可以忽略不计。
ps
在本机命令的遗传基因指向 SysV 的系统上,您可以使用
ps -e |grep cron
或者
ps -el |grep cron
获得包含 pid 和进程名称以外的内容的列表。当然,您可以使用-o <field,field,...>
选项选择要打印的特定字段。
解决方案 8:
我使用pgrep -l httpd
但不确定它是否存在于任何平台上...
谁可以在 OSX 上确认?
解决方案 9:
如果命令“ps”、“pidof”和 rest 不可用,则可以使用此方法。我个人在我的工具/脚本/程序中非常频繁地使用 procfs。
egrep -m1 "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3
稍微解释一下发生了什么:
-m1 – 第一次匹配时停止进程
“mysqld$|httpd$” - grep 将匹配以 mysqld 或 httpd 结尾的行
/proc/[0-9]* - bash 将匹配以任意数字开头的行
剪切 - 仅通过分隔符 '/' 拆分输出并提取字段 3
解决方案 10:
您应该知道您的进程的 PID。
当你启动它时,它的 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
指令。
解决方案 11:
这些答案都不适合我,所以这里是我的:
process="$(pidof YOURPROCESSHERE|tr -d '
')"
if [[ -z "${process// }" ]]; then
echo "Process is not running."
else
echo "Process is running."
fi
解释:
|tr -d '
'
这将删除终端创建的回车符。其余部分可以通过这篇文章进行解释。
解决方案 12:
这将打印基本名称为“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”,则表示进程未运行。该命令假定进程路径不包含空格。我尚未使用挂起进程或僵尸进程对此进行测试。
gwak
在 Linux 中作为替代方案进行了测试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.
"
else printf "not running.
"; fi
printf "Listing of matching processes (PID and process name with command line arguments):
"
isProcessRunning "$process"
解决方案 13:
这是我的版本。特点:
检查准确的程序名称(函数的第一个参数)。搜索“mysql”将不会匹配正在运行的“mysqld”
搜索程序参数(函数的第二个参数)
脚本:
#!/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 ' ' ' ' | 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
解决方案 14:
[ $pid ] && [ -d /proc/$pid ] && command
如果你知道 pid
解决方案 15:
以下 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
%s
" "$1" "$cmd" ||
printf "%s is not running
" $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
选项,并且免费使用 shell,尽管它很受欢迎,但不能保证在每台 Unix/Linux 机器上都存在 ( bash
)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件