我正在将top命令输出写入文本文件。 我正在尝试编写一个简单的bash脚本来计算已用内存的百分比并发送一个 如果内存使用百分比超过,请发送电子邮件,比如说90%。
这是我到目前为止的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" test@test.com
当我保存并执行脚本时,我收到错误“没有这样的文件或目录”:
-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$
有人可以协助吗?我是bash脚本的新手,这是我的第一个脚本。
谢谢
答案 0 :(得分:4)
我不会重复其他答案的内容;相反,当你只需要有关系统内存使用情况的信息时,我会质疑解析top
输出的智慧。
top
的输出适用于人类,并且还包含许多不需要且生成成本高昂的每个过程信息。 free
的输出更适合这种特定用途。
其次,根据脚本中的计算判断,您似乎并不了解在Linux和其他类Unix系统上测量系统内存使用情况的方式。与其他操作系统相反,使用的内存大小包含用于磁盘缓存和其他缓冲区的内存。在任何已经启动一段时间的系统上,空闲内存趋向于零 - 未使用的内存是浪费的内存。
找出进程使用的内存量的第一步是从已用内存大小中减去缓冲区使用的内存量。但即便如此,在现代系统中也是不够的 - 即使free
和top
在某种程度上也会出错,如this older answer of mine中所述。
答案 1 :(得分:2)
这里有一些问题。
首先,这不符合您的要求。
USEDMEM=/home/modadm/top-output.txt | grep "Mem" | cut -c 25-31
您无法将文件名传递给命令。您实际上想要将文件的内容传递给命令。你可以用'猫'做到这一点。但是,grep实际上是设计用于在文件中搜索,因此您可以执行
USEDMEM=$(grep "Mem" /home/modadm/top-output.txt | cut -c 25-31)
请注意$(cmd)是在子shell中执行命令的方式。也就是说,您可以运行一些命令来计算脚本中变量的值。你也可以使用`cmd`(反引号;通常在波浪键上),但语法不太明确。
同样,您可能希望在子shell中计算此结果。另外,在分配变量时不要使用$。
$USEDPCT='echo $USEDMEM / $MAXMEM * 100 | bc'
这可以改写为
USEDPCT=$(echo "scale=3; $USEDMEM / $MAXMEM * 100" | bc)
最后,您希望将变量的内容传递到邮件程序中。管道预计程序在左侧。您可以通过将变量的值回显到管道中来实现此目的。
echo "$USEDPCT" | mail -s "Test Email from MOD Server" test@test.com
将所有东西重新组合在一起:
#!/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" test@test.com
答案 2 :(得分:2)
其他人已经指出了代码的问题,但是有更简单的选择,即根本不解析top
输出。使用/proc/meminfo
和awk
- 您将不需要临时文件。
$ awk '/MemTotal:/{total=$2} \
/MemFree:/{free=$2} \
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
将其传递给mail
或您想要的任何内容。
答案 3 :(得分:0)
我已更正您的语法错误。 PL。注意使用命令替换, 就像你写的那样
MAXMEM=/home/modadm/top-output.txt | grep "Mem" | cut -c 7-14.
这是错的,你需要写
grep "Mem" /home/modadm/top-output.txt | cut -c 7-14
然后将其包含在反引号中(左侧的键位于tab键上),以将最终值赋给变量。 你也写过,
$USEDPCT='echo $USEDMEM / $MAXMEM * 100 | bc'
美元符号使用错误。当您使用值时,应该使用$ 一个变量。引号应该是`(反引号)而不是'(单引号)。反引号表示命令将替换为命令的输出。 对于浮点bc也需要设置比例。
PL。看到修改后的代码。希望这可以帮助。 PL。注意我没有检查邮件命令的功能,如果它正在发送邮件。
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" test@test.com
答案 4 :(得分:0)
尝试以下脚本。
#! /bin/bash
memusage=`top -n 1 -b | grep "Mem"`
MAXMEM=`echo $memusage | cut -d" " -f2 | awk '{print substr($0,1,length($0)-1)}'`
USEDMEM=`echo $memusage | cut -d" " -f4 | awk '{print substr($0,1,length($0)-1)}'`
USEDMEM1=`expr $USEDMEM \* 100`
PERCENTAGE=`expr $USEDMEM1 / $MAXMEM`%
echo $PERCENTAGE | mail -s "Test Email" test@test.com