我有一个脚本名称 server.sh
#!/bin/bash
process_count=$(ps aux | grep server.sh | grep -v grep | wc -l )
echo "total process running:"
echo $process_count
... other script code
当我运行脚本时,我得到的输出为
./server.sh
total process running:
2
为什么我得到的进程计数为 2 而不是 1?我只运行一个脚本,并且还排除了 grep 进程。即使使用 pgrep -f server.sh 并排除 pgrep 也会得到 2 作为进程计数。
答案1
如果
ps | grep | grep -v grep
或pgrep
显示两个进程,那么您有两个匹配的进程正在运行。通过运行管道来亲自查看ps ...
而不通过管道进入wc -l
.那不是
pgrep
,pgrep
是一个完全独立的程序ps
。请参阅man pgrep
详细信息,但总而言之,运行pgrep -f server.sh | wc -l
这通过
ps
管道输送到grep
, thengrep -v
, thenwc -l
。这与它自己的管道进程之一(第一个grep
)匹配,因为grep
正在搜索“server.sh”,它恰好是 的命令行参数grep server.sh
。避免这种情况的通常方法(从以前存在的日子开始
pgrep
)是/曾经是grep
为了某些事情惯于匹配它自己的命令行,例如grep [s]erver.sh
或grep server\\.sh
,或者只使用 awk:ps aux | awk '/[s]erver\.sh/ {count++}; END {print count}'
或者如果您想获取匹配 PID 的列表而不是计数:
ps aux | awk '/[s]erver\.sh/ {print $1}'
此外,
ps
Linuxprocps
软件包中的 长期以来一直支持-C cmdlist
对进程可执行文件名称的基本名称部分进行精确匹配的选项。例如,
ps -C apache2
将列出 apache2 进程,即使ps aux | grep [a]pache2
显示完整的进程名称实际上是/usr/sbin/apache2
。这不是正则表达式匹配,而是基本名称的精确匹配 -ps -C apache
不会显示apache2
进程。从
man ps
:
-C cmdlist
按命令名称选择。这将选择其可执行名称在 中给出的进程
cmdlist
。注意:命令名称与命令行不同。以前版本的
procps
内核将此命令名称截断为 15 个字符。两者都不再存在此限制。如果您仅依赖于匹配 15 个字符,则可能不再获得匹配项。