BASH - grep ps 具有序列/递增数字的数据

BASH - grep ps 具有序列/递增数字的数据

我有一个 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.;这将合并ClockService1ClockService2

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"

在此示例中,我正在catting 文件而不是调用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

相关内容