我编写了一个脚本来检查基于 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
进程,请使用pkill
with -o
,并使用-n
来仅终止最新的进程。请参阅pkill
手册。
另请注意
variable=$( echo `somecommand` )
更好地写成
variable=$( some_command )
除非您依赖 shell 会根据结果进行分词和文件名扩展some_command
(您不是)的事实。