尝试通过列名和进程名称获取值时得到错误的值

尝试通过列名和进程名称获取值时得到错误的值

我正在编写一个脚本来监视稳定性测试期间的 CPU 和内存利用率,最后我想将其呈现在图表或其他可视化工具中。为此,我尝试按列名称从 top 命令中提取 %CPU 和 %MEM

   ##to get indexes of columns I need 
   indexCPU=$(top -b -n 1 | grep PID | tr -s ' ' '\n' | nl -nln |  grep "%CPU" | cut -f1)
   infexMEM=$(top -b -n 1 | grep PID | tr -s ' ' '\n' | nl -nln |  grep "%MEM" | cut -f1)

   ## get values from top in a while loop
   while [ $UPTIME -lt $DURRATION ]; do
   scpu=$(top -b -n 1| grep -w squeezer | tr -s ' ' | cut -d ' ' -f $indexCPU )
   smem=$(top -b -n 1| grep -w squeezer | tr -s ' ' | cut -d ' ' -f $infexMEM )
   echo "$scpu     $smem" >> stabilityTestUsageM.txt
   sleep 300
   done

现在,当我这样做时,有时它会得到正确的值,但在其他情况下,我会得到左侧的值

例如,我得到了输出

    S

为了这:

    top -b -n 1| grep -w squeezer | tr -s ' ' | cut -d ' ' -f $indexCPU

这是 top -b -n 1| 的结果grep -w 挤压机:

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    8048 root      20   0 1953716 442376   8460 S   0.0  2.7   0:30.97 squeezer

你知道出了什么问题吗?

谢谢

答案1

top您的方法的问题在于,在识别字段 nr 的第一阶段,您在计数中省略了“空字段”(由 输出中的前导空格产生)。但是,cut将分隔符设置为单个空格会将以空格开头的行解释为开头有一个空字段。因此,与字段计数方式相比,由您确定的字段编号nl -nln少了 1 。cut

然而,作为一般规则,我建议awk

top -b -n 1 | awk '$NF=="squeezer" {print $9}'

应打印最后一个空格分隔字段(命令)为“squeezer”的行的第 9 个字段(CPU 使用率)。

如果您想通过名称来识别 CPU 字段以便确定,可以使用以下方法:

top -b -n 1 | awk '!i&&/PID/{for (i=1;i<=NF;i++) {if ($i=="%CPU") break}} '$NF=="squeezer" {print $i}}'

这将首先迭代包含列标题的行中的所有字段,并在到达读取的字段(因此包含相关字段编号)PID时中断循环。然后,它从最后一个字段是您要分析的命令的行中打印该字段。作为保护措施,仅考虑包含该字符串的第一行(以防任何进程名称也可能包含该字符串)。%CPUiPID

请注意,这种相当简单的方法仅在列出不带参数的命令时才有效,即最后一个空格分隔的字段实际上只是命令,而不是任何命令行参数。

对于另一部分,您应该根据网站指南提出一个单独的问题。

相关内容