脚本Linux - awk

时间:2012-11-28 16:18:20

标签: awk

我有小问题。我需要解释一下,awk是什么。

我需要编写一个脚本来监视系统上的负载是否过载(CPU,RAM)并写入消息。

我有这个:

if 
[[ $(bc <<< "$(top -b -n1 | grep ^Cpu | awk -F': ' '{print $2}' | awk -F% '{print $1}') >= 100") -eq 1 ]] ; then echo '...'; 
fi

这是针对CPU的。任何人都能解释一下这个例子中的awk是什么吗?怎么会有内存的问题?

2 个答案:

答案 0 :(得分:0)

第一个awk调用将在任何行上打印第二个标记,其中标记由冒号或空格分隔。

第二个将在任意行中打印第一个令牌,其中令牌以百分号(%)分隔。

要在Linux系统上获取已用内存:

free | awk '/Mem:/ {print $3;}'

答案 1 :(得分:0)

这是一个非常脆弱的脚本,基于看似旧版 top 的内容。虽然检查这段脚本非常容易 - 所以,让我们来看看它。我们从以下开始:

top -b -n1

其中(阅读顶部的手册)将顶部置于批处理模式(这意味着我们不想与顶部进行交互式播放,而是想要将输出发送到另一个命令)并输出1次迭代。这将使我们输出如下:

$ top -b -n1
top - 10:48:33 up 1 day, 22:51,  3 users,  load average: 1.21, 1.27, 1.03
Tasks: 262 total,   2 running, 260 sleeping,   0 stopped,   0 zombie
%Cpu(s): 14.5 us,  5.2 sy, 11.3 ni, 67.3 id,  1.6 wa,  0.0 hi,  0.1 si,  0.0 st
KiB Mem:   8124692 total,  6722112 used,  1402580 free,   384188 buffers
KiB Swap:  4143100 total,   430656 used,  3712444 free.  2909664 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
11012 user1     20   0  426412  14436   5740 R  97.1  0.2  19:27.98 dleyna-renderer
 4579 root      20   0  286480 152924  31152 S  13.0  1.9  24:15.49 Xorg
    1 root      20   0  185288   4892   3352 S   0.0  0.1   0:02.52 systemd
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.02 kthreadd
    3 root      20   0       0      0      0 S   0.0  0.0   0:02.77 ksoftirqd/0
    5 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H
    7 root      20   0       0      0      0 S   0.0  0.0   1:32.00 rcu_sched

当我们将其传输到 grep ^ Cpu ...好吧,看起来这是我们发现一些破损的地方,表明顶部的< / strong>我们在这个答案中使用的输出可能与原始脚本预期的版本不同。看起来意图是匹配 ^%Cpu 。这是更正的部分:

$ top -b -n1 | grep ^%Cpu
%Cpu(s): 14.6 us,  5.2 sy, 11.2 ni, 67.3 id,  1.6 wa,  0.0 hi,  0.1 si,  0.0 st

管道的下一部分是摆脱'%Cpu(s):'件:

$ top -b -n1 | grep ^%Cpu | awk -F': ' '{print $2}'
15.1 us,  5.0 sy, 10.8 ni, 67.4 id,  1.6 wa,  0.0 hi,  0.1 si,  0.0 st

然后下一篇...... awk -F%'{print $ 1}' - 对于这个答案的 top ,因为脚本正在寻找打印符号左侧的内容 - 并且输出中没有。所以...我们想知道我们需要从哪里开始。

从脚本的其余部分......将管道的结果与100进行比较...因此,我假设脚本要解析的 top 的版本具有百分比第一列中的CPU利用率总计...在我们的 top 输出版本中,所有内容都以更加精细的方式进行了细分。以下是前一个输出的细分:

 15.1% -- spent in normal priority user/applications
  5.0% -- spent in system/kernel
 10.8% -- spent in low priority batch or daemon jobs
 67.4% -- spent "idle"
  1.6% -- spent waiting for I/O to complete
  0.0% -- spent in servicing HW interrupts
  0.1% -- spent in servicing software interrupts
  0.0% -- spent stolen by another VM running on the HW
------------------------------------------------------
100.0% -- Total

...因此,在现代Linux系统上, top 提供了更多信息,也许我们需要以不同方式查看问题。在这种情况下,我们可以将(idle * 10)视为度量 - 就像在shell中一样,我们只有整数数学和比较可供我们使用。所以,我们会稍微调整脚本......当我们处理它时,让我们摆脱管道中的 grep ,因为这可以通过 awk轻松完成也是:

$ top -b -n1 | awk -F, '/^%Cpu/ {print $4}'
 67.8 id

现在让我们调整它,使它只给我们空闲值乘以10:

$ top -b -n1 | awk -F, '/^%Cpu/ { sub(/id/,"",$4); print $4*10 }'
678

好的,原始脚本的下一部分使用 bc 来查看我们是否100%使用。由于我们现在正在考虑闲置而不是利用,我们希望与原始脚本相反。此外,我们现在不需要 bc 的复杂性,因为输出被缩放为整数。我们在比较中使用shell吗?

$ if [ $(top -b -n1 | awk -F, '/^%Cpu/ { sub(/id/,"",$4); print $4*10 }') -le 0 ]; then echo '...'; fi

就是这样。

这个答案都是为了说明代码是如何工作的 - 如何通过管道解释和解析 top 的输出,如何解决一个脚本执行的问题,以及如何修复脆弱/破碎的脚本。然而,原始脚本不仅脆弱,而且几乎被设计破坏了。我们用来检测超载系统的度量标准更像是在 top 命令的输出的第一行找到的“平均负载”,或者更好的是可以从输出中解析出来的正常运行时间命令。

找出过载的方法可能是查看负载平均值除以cpu的数量。可以很容易地找到cpu的数量来解析/ proc / cpuinfo:

$ grep ^processor /proc/cpuinfo | wc -l
4

以下是一个例子,其中超过15分钟的400%负载被认为是连续加载阈值:

load=$(uptime | awk -F, '{ print $(NF) * 1.0 }')
proc=$(grep ^processor /proc/cpuinfo | wc -l)
plod=$(awk "BEGIN { x = 100 * $load / $proc; print int(x) + int(x+x)%2 }")

if [ $plod -gt 400 ]; then echo '...'; fi

注意: int(x)+ int(x + x)%2 是一个舍入函数

对于系统上的可用内存量,我喜欢 schtever 的答案 - 除了我会使用第4列而不是第3列并检查内存不足。