我编写了一个脚本来检查进程是否在 Ubuntu 服务器(14.04)上运行,它工作正常,但在测试它时,我发现它不包括在其他终端中运行的顶级命令计数
内容check-process.sh
#!/bin/sh
OK=1
CRITICAL=0
PROCESS_NUM=$( ps -ef | grep $1 | grep -v "grep "|grep -v "sh"|wc -l )
#echo $PROCESS_NUM
if [ $PROCESS_NUM = $OK ]
then
echo "OK"
elif [ $PROCESS_NUM = $CRITICAL ]
then
echo "CRITICAL"
elif [ $PROCESS_NUM > $OK ]
then
echo "MULTIPLE process are runing"
else
echo "error"
fi
我top
在两个终端中运行命令,并按如下方式运行此脚本:
./check-process.sh top
输出是0 CRITICAL
,但是当我运行正常命令时,ps -ef |grep -v "grep "| wc -l
它给出两个计数。
答案1
正如对该问题的评论中指出的那样,测试 with>
不进行算术比较,而是进行字典比较(2 > 100
例如,这是正确的),但仅限于[[ ... ]]
.其中[ ... ]
有一个普通的输出重定向运算符。
grep -v "grep "
和过滤grep -v "sh"
还可以从输出中过滤掉合法进程ps
(例如,如果您想在grep
进程上使用脚本)。
以下脚本实现相同的逻辑,但使用pgrep
:
#!/bin/bash
cmd=$1
pids=( $( pgrep "$cmd" ) )
case "${#pids[@]}" in
0) echo 'No such process' ;;
1) echo 'One such process' ;;
*) echo 'Many such processes'
esac
如果您在另一个终端中运行一个top
命令,则运行此脚本作为top
其参数将报告One such process
.在两个终端中运行top
将使其报告Many such processes
。
使用变量,例如使用:
#!/bin/bash
cmd=$1
pids=( $( pgrep "$cmd" ) )
critical=0
ok=1
case "${#pids[@]}" in
$critical) echo 'No such process' ;;
$ok) echo 'One such process' ;;
*) echo 'Many such processes'
esac
该脚本将返回的 PID 保存pgrep
到一个数组中(这就是为什么这是一个bash
脚本而不是sh
脚本的原因),然后根据数组的长度进行测试。
以下是对 的改编sh
:
#!/bin/sh
cmd=$1
set -- $( pgrep "$cmd" )
critical=0
ok=1
case "$#" in
$critical) echo 'No such process' ;;
$ok) echo 'One such process' ;;
*) echo 'Many such processes'
esac
该sh
脚本使用我们可以访问的唯一数组,即位置参数数组。这些(位置参数)被设置为由pgrep
with生成的 PID,set
并且这些参数的数量来自$#
。