bash 使用 LINUX top 命令计算已用内存百分比

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12118767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 03:06:59  来源:igfitidea点击:

Using LINUX top command to compute used memory percentage

linuxbash

提问by user765081

I am writing the top command output to a text file. I am trying to write a simple bash script to calculate the percentage of used memory and send an email if the memory used percentage exceeds, say 90%.

我正在将顶部命令输出写入文本文件。我正在尝试编写一个简单的 bash 脚本来计算已用内存的百分比,并在内存使用百分比超过 90% 时发送电子邮件。

Here is the bash script I have thus far.

这是我迄今为止的 bash 脚本。

#!/bin/bash
top -n 1 -b | grep "Mem" > /home/modadm/top-output.txt
MAXMEM=/home/modadm/top-output.txt | grep "Mem" | cut -c 7-14 
USEDMEM=/home/modadm/top-output.txt | grep "Mem" | cut -c 25-31
$USEDPCT='echo $USEDMEM / $MAXMEM * 100 | bc'
$USEDPCT | mail -s "Test Email from MOD Server" [email protected]

When I save and execute the script, I get the error "No such file or directory":

当我保存并执行脚本时,出现错误“没有这样的文件或目录”:

-bash-3.2$ ./memcheck.sh
./memcheck.sh: line 4: =echo $USEDMEM / $MAXMEM * 100 | bc: No such file or directory
Null message body; hope that's ok
-bash-3.2$ 

Can someone assist? I am a newbie to bash scripting and this is my first script.

有人可以帮忙吗?我是 bash 脚本的新手,这是我的第一个脚本。

Thank you

谢谢

回答by thkala

I will not repeat the content of the other answers; instead I will question the wisdom of parsing the output of top, when all you need is information on the system memory usage.

其他答案的内容我就不重复了;相反top,当您只需要有关系统内存使用情况的信息时,我会质疑解析 的输出是否明智。

The output of topis intended for humans and also contains a lot of per-process information that is both unneeded and expensive to produce. The output of freeis far more suitable for this particular use.

的输出top旨在供人类使用,并且还包含大量不需要且生产成本高昂的每进程信息。的输出free更适合这种特殊用途。

Secondly, judging by the calculations in your script, you do not seem to understand the way system memory usage is measured on Linux and other Unix-like systems. Contrary to the otherOS, the used memory size contains the memory used for disk caches and other buffers. On any system that has been up for some time the free memory tends towards zero - unused memory is wasted memory.

其次,从脚本中的计算来看,您似乎不了解在 Linux 和其他类 Unix 系统上测量系统内存使用情况的方式。与其他操作系统相反,已用内存大小包含用于磁盘缓存和其他缓冲区的内存。在任何已经运行一段时间的系统上,空闲内存趋于零 - 未使用的内存是浪费的内存。

A first step towards finding out the amount of memory used by processes would be to subtract the amount of memory used for buffers from the used memory size. But even that would not be enough on a modern system - even freeand topget it wrong to a degree, as mentioned in this older answer of mine.

找出进程使用的内存量的第一步是从已用内存大小中减去用于缓冲区的内存量。但即使这样,也不足以现代系统上-甚至freetop搞错了一定程度,如在提到我的这个旧的答案

回答by Mat

Others have pointed out problems with your code, but there are much easier options for this, namely not parsing topoutput at all. Use /proc/meminfo, and awk- you won't need a temporary file.

其他人指出您的代码存在问题,但对此有更简单的选择,即根本不解析top输出。使用/proc/meminfo, 和awk- 您不需要临时文件。

$ awk '/MemTotal:/{total=} \
       /MemFree:/{free=} \
       END{ \
        print "Free mem percent: "(free*100/total); \
        print "Used mem percent: "((total-free)*100/total) \
       }' /proc/meminfo 

Free mem percent: 87.7348
Used mem percent: 12.2652

Pipe that to mailor whatever you want.

管它mail或任何你想要的。

回答by Mat

You have a few problems here.

你在这里有一些问题。

First, this doesn't do what you want it to do.

首先,这不会做你想要它做的事情。

USEDMEM=/home/modadm/top-output.txt | grep "Mem" | cut -c 25-31

You can't pipe a filename into a command. You actually want to pipe the contents of the file into the command. You can do that with 'cat'. However, grep is actually designed to search within a file so you can do

您不能将文件名通过管道传输到命令中。您实际上想将文件的内容通过管道传输到命令中。你可以用'cat'来做到这一点。但是,grep 实际上是为在文件中搜索而设计的,因此您可以执行以下操作

USEDMEM=$(grep "Mem" /home/modadm/top-output.txt | cut -c 25-31)

Note that $(cmd) is how you execute a command in a subshell. i.e., you can run some commands to compute the value of a variable in your script. You can also use `cmd` (backticks; usually on the tilde key) but that syntax is less clear.

请注意, $(cmd) 是您在子 shell 中执行命令的方式。即,您可以运行一些命令来计算脚本中变量的值。您也可以使用 `cmd`(反引号;通常在波浪号键上),但该语法不太清楚。

Again, you probably want to calculate this result in a subshell. Also, don't use $ when assigning to variables.

同样,您可能希望在子 shell 中计算此结果。此外,在分配给变量时不要使用 $。

$USEDPCT='echo $USEDMEM / $MAXMEM * 100 | bc'

This can be rewritten as

这可以改写为

USEDPCT=$(echo "scale=3; $USEDMEM / $MAXMEM * 100" | bc)

Finally, you want to pipe the contents of the variable into the mail program. The pipe is expecting a program to be on the left hand side. You do this by echo'ing the value of the variable into the pipe.

最后,您希望将变量的内容通过管道传送到邮件程序中。管道期望程序位于左侧。您可以通过将变量的值回显到管道中来完成此操作。

echo "$USEDPCT" | mail -s "Test Email from MOD Server" [email protected]

To put everything back together:

将所有内容重新组合在一起:

#!/bin/bash
top -n 1 -b | grep "Mem" > /home/modadm/top-output.txt
MAXMEM=$(grep "Mem" /home/modadm/top-output.txt | cut -c 7-14)
USEDMEM=$(grep "Mem" /home/modadm/top-output.txt | cut -c 25-31)
USEDPCT=$(echo "$USEDMEM / $MAXMEM * 100" | bc -l)
echo "$USEDPCT" | mail -s "Test Email from MOD Server" [email protected]

回答by Kam Aggarwal

Try the following script.

试试下面的脚本。

#! /bin/bash

memusage=`top -n 1 -b | grep "Mem"`
MAXMEM=`echo $memusage | cut -d" " -f2 | awk '{print substr(
MAXMEM=/home/modadm/top-output.txt | grep "Mem" | cut -c 7-14.
,1,length(
 grep "Mem" /home/modadm/top-output.txt | cut -c 7-14
)-1)}'` USEDMEM=`echo $memusage | cut -d" " -f4 | awk '{print substr(
$USEDPCT='echo $USEDMEM / $MAXMEM * 100 | bc'
,1,length(
top -n 1 -b | grep "Mem" > /home/modadm/top-output.txt
MAXMEM=`grep "Mem" /home/modadm/top-output.txt | cut -c 7-14`
USEDMEM=`grep "Mem" /home/modadm/top-output.txt | cut -c 25-31`
USEDPCT=`echo   "scale=2; $USEDMEM / $MAXMEM * 100" | bc `
echo $USEDPCT | mail -s "Test Email from MOD Server" [email protected]
)-1)}'` USEDMEM1=`expr $USEDMEM \* 100` PERCENTAGE=`expr $USEDMEM1 / $MAXMEM`% echo $PERCENTAGE | mail -s "Test Email" [email protected]

回答by Tanmoy Bandyopadhyay

I have corrected your syntax errors. Pl. note the use of command substitution, like you have written

我已更正您的语法错误。PL。注意命令替换的使用,就像你写的那样

##代码##

This is wrong, you need to write

这是错误的,你需要写

##代码##

and then enclose it within backquotes(the key at the lefthand side over tab key) to assign final value to a variable. Also you have written,

然后将其括在反引号内(tab 键左侧的键)以将最终值分配给变量。你也写过,

##代码##

The dollar sign is used wrongly. $ should be used when you are using the value of a variable.The quotes should be ` (back quote) and not '(single quote). Backquote means the command will be substituted with the output of the command. Also for floating point bc needs a scale to be set.

美元符号使用错误。当您使用变量的值时,应该使用 $。引号应该是 `(反引号)而不是 '(单引号)。反引号意味着命令将被命令的输出替换。同样对于浮点 bc 需要设置一个比例。

Pl. see the modified code. Hope this helps. Pl. note I have not checked the functionality of the mail command that if it is sending mail or not.

PL。查看修改后的代码。希望这可以帮助。PL。注意我没有检查邮件命令的功能,如果它正在发送邮件。

##代码##