如果从脚本运行,pgrep 会返回与在终端中运行不同的结果

如果从脚本运行,pgrep 会返回与在终端中运行不同的结果

我编写了一个脚本来检查基于 OpenWrt 的系统中有多少个进程实例正在运行。如果我在终端中运行以下命令

COUNT_PS=$(echo `ps -w | grep -v grep | grep upmpdcli | wc -l`)
root@SHAULA-720:~# echo $COUNT_PS

结果是

1

下面是 shell 脚本的代码,如果我运行这个脚本,结果是 4 而不是 1

#!/bin/ash

#for debug 
ps -w | grep -v grep | grep upmpdcli



COUNT_PS=$(echo `ps -w | grep -v grep | grep upmpdcli | wc -l`)
echo we have $COUNT_PS instances for upmpdcli;
logger we have $COUNT_PS instances for upmpdcli;

if [[ $COUNT_PS == 1 ]]; then        
    logger "we have only one instance"


 #HERE PUT CODE TO START NEW PROCESS
elif [[ $COUNT_PS == 2 ]]; then
    logger "we have 2 instances lets kill all and start a single"
    kill -9 `pgrep upmpdcli`

elif [[ $COUNT_PS == 0 ]]; then
    logger "we have no instance lets wait for cron to start it"


else
    logger "we have $COUNT_PS  instances"
fi

所以如果我运行/etc/upmpd-check.sh结果we have 4 instances for upmpdcli对我来说很奇怪。

我在这里缺少什么?

在此输入图像描述 在此输入图像描述

答案1

主要的困惑来自于ps | grep与脚本名称匹配的管道,其中包括字符串upmpdcli

这样pgrep您就不会遇到相同的问题,因为pgrep默认情况下仅查看命令名称,并且不会误upmpdcli-check认为upmpdcli.

理想情况下,您会使用

pgrep -x /usr/bin/upmpdcli

获取该进程的 PID。

要终止该进程或那些进程,请使用

pkill -x /usr/bin/upmpdcli

也就是说,做不是使用 PID pgrep(因为这些可能不是最新的)。

要仅终止最旧的upmpdcli进程,请使用pkillwith -o,并使用-n来仅终止最新的进程。请参阅pkill手册。


另请注意

variable=$( echo `somecommand` )

更好地写成

variable=$( some_command )

除非您依赖 shell 会根据结果进行分词和文件名扩展some_command(您不是)的事实。

相关内容