我有一个 bash for 循环,它迭代 ps 中的进程列表。这个想法是查看进程是否正在运行并计算输出。下面是要迭代的示例列表
BOX.Container_Philips1_Primary_X1
BOX.Container_Philips_Primary_X1
BOX.Container_Philips3_Primary_X1
BOX.Container_Server1_X1
BOX.Container_Node1_X1
BOX.Container_Host1_X1
BOX.Container_ClockService1_X1
BOX.Container_ClockService2_X1
我的bash代码如下
#PSUEDO
procs=(
Philips 1
Node 1
Host 1
Server 1
Philips1 1
Philips3 1
ClockService 2)
#END PSUEDO
for (( i=0 ; i<"${#procs[@]}" ; i++ ))
do
name=$(echo "${procs[i]}" | awk '{print $1}')
configured_count=$(echo "${procs[i]}" | awk '{print $2}')
running=()
while read -r line
do
running+=("${line}")
done < <(ps -u user -f | grep "BOX.${name}" | grep -v grep)
if [[ "${configured_count}" -gt "${#running[@]}" ]]; then
result+=$(echo -e "\n[FAIL] ${name} - configured count: ${configured_count} running count: ${#running[@]}")
elif [[ "${#running[@]}" -gt "${configured_count}" ]]; then
result+=$(echo -e "\n[WARN] ${name} - configured count: ${configured_count} running count: ${#running[@]}")
else
result+=$(echo -e "\n[PASS] ${name} - configured count: ${configured_count} running count: ${#running[@]}")
fi
done
迭代时,name=Philips会返回计数3(错误),name=Philips1或Philips3;计数为 1(所需)。我需要一些关于如何处理飞利浦线路的想法,但不要错误地计算“主机”、“节点”条目。从体系结构的角度来看,飞利浦进程是不同的,而 ClockService 例如是负载平衡的。我想说 ClockService 的计数为 2,但每个 Philips 的计数应该为 1。
答案1
这个想法是建立一个grep
更符合你想要的模式。请记住.
匹配任何字符。
因此,例如,BOX.Container_${name}_
成为一个有用的模式。现在Philips
不同于Philips1
.您可以在要合并条目的位置进行搜索ClockService.
;这将合并ClockService1
和ClockService2
。
grep -c
我们还可以使用 和 use 来简化一些测试[B]OX
来避免这种grep -v
要求。
所以生成的代码看起来像这样:
declare -A procs=(
[Philips]=1
[Node.]=1
[Host.]=1
[Server.]=1
[Philips1]=1
[Philips3]=1
[ClockService.]=2)
# psout=$(ps -u user -f)
psout=$(cat psout)
for i in "${!procs[@]}"
do
name=$i
configured_count=${procs[$i]}
running=$(echo "$psout" | grep -c "[B]OX.Container_${name}_")
if [[ "$configured_count" -gt "$running" ]]; then
result+=$(echo -e "\n[FAIL] ${name} - configured count: ${configured_count} running count: $running")
elif [[ "$running" -gt "$configured_count" ]]; then
result+=$(echo -e "\n[WARN] ${name} - configured count: ${configured_count} running count: $running")
else
result+=$(echo -e "\n[PASS] ${name} - configured count: ${configured_count} running count: $running")
fi
done
echo "$result"
在此示例中,我正在cat
ting 文件而不是调用ps
,但您可以了解如何更改此设置。
% cat psout
BOX.Container_Philips1_Primary_X1
BOX.Container_Philips_Primary_X1
BOX.Container_Philips3_Primary_X1
BOX.Container_Server1_X1
BOX.Container_Node1_X1
BOX.Container_Host1_X1
BOX.Container_ClockService1_X1
BOX.Container_ClockService2_X1
% bash code
[PASS] Node. - configured count: 1 running count: 1
[PASS] ClockService. - configured count: 2 running count: 2
[PASS] Philips1 - configured count: 1 running count: 1
[PASS] Philips3 - configured count: 1 running count: 1
[PASS] Server. - configured count: 1 running count: 1
[PASS] Philips - configured count: 1 running count: 1
[PASS] Host. - configured count: 1 running count: 1
答案2
感谢大家的意见和评论。我没有提到的输入的另一个元素是分隔进程类型的前缀,因此它们不仅仅是“BOX”。 ps 输入示例
BOX.CC_Container_Philips1_Primary_X1
BOX.CC_Container_Philips_Primary_X1
BOX.CC_Container_Philips3_Primary_X1
BOX.Container_Server1_X1
BOX.Container_Node1_X1
BOX.Container_Host1_X1
BOX.Container_ClockService1_X1
BOX.Container_ClockService2_X1
所以我最终做的是根据类型编写一个条件(是否为“CC”?),然后对其运行单独的循环。可能不是最好的方法,但它确实有效。
#name = list of process names from SQL, parsed into an array
type=$(echo "${name}" | awk -F"_" '{print $1}')
if [[ "${type}" == "CC" ]]; then
while read -r line
do
running+=("${line}")
done < <(ps -u esmadmin -f | grep "${DOMAIN}.${name}_" | grep -v grep)
else
while read -r line
do
running+=("${line}")
done < <(ps -u esmadmin -f | grep "${DOMAIN}.${name}" | grep -v grep)
fi