Bash评价莫名其妙

当一个数字大于另一个数字时,我试图让一个脚本去做一些事情,在这种情况下,当系统负载平均值超过一个定义的值时。

所有这些都在评估标准之外。

虽然我build立了一些网站的另一台服务器,我试图保持阿帕奇排队,原因并不重要,但是这个脚本已经在负载平均值低于15的系统上testing和testing,脚本打印出来:

“检查是4.68和最大是15.00”DESPITE if条件告诉它不要打印任何东西,如果检查的价值不大于最大负载,这是不是。

我不是bash大师,我有一个胡子,但没有凉鞋,我已经尝试了各种不同的方括号和引用的样式,但我不明白为什么这个脚本打印什么的时候$ check小于$ max_load 。

这是Debian 6,GNU bash,版本4.1.5(1)-release-(x86_64-pc-linux-gnu)

#!/bin/bash check=`cat /proc/loadavg | sed 's/./ /' | awk '{print $2}'` max_load='15.00'; high_load_log='/var/log/apache2/apache_high_load_restart.log'; apache_init='/etc/init.d/apache2'; if [[ $check > $max_load ]]; then echo " check is $check and max is $max_load"; #$apache_init stop sleep 5; #$apache_init restart echo "$(date) : Apache Restart due to load of | $check |" >> $high_load_log; fi 

在负载约为4的系统上,该脚本输出:

 "check is 4.68 and max is 15.00" 

有谁知道为什么?

任何帮助,并build议良好的首发凉鞋将不胜感激!

这是不行的。 >内部的操作符[[比较sorting顺序 ,而不是值。 所以….

 $ echo -e '4.68\n15.00'|sort 15.00 4.68 

…因为在1之后有4种,这意味着[[ 4.68 > 15.00 ]]是真的。 而且你不能使用-gt ,因为那需要整数。

如果你只关心整数阈值,这是简单的修复 – 截断在. ,用-gt ,然后你去。 否则,使用bc – 请参阅https://unix.stackexchange.com/questions/24721/how-to-compare-to-floating-point-number-in-a-shell-script

根据文档, <>是一个词法sorting 。 我不确定,但我很确定,如果你使用类似的东西,这将是相同的。 随着sorting, 15.00是在4.68之前,因为它基本上是逐字符sorting。 所以1在大部分地区是在4之前。

既然你的示例值4.68将在15.0之后进行词法sorting,那么>返回true。

你几乎肯定希望你的string被视为数字,所以你可以使用-gt-lt ,但是这些被限制为整数。

参考: http : //www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html

string1 <string2如果string1按照字典顺序sorting,则为true。

string1> string2如果string1按照字典顺序sorting,则返回true。

谢谢大家,在我的Debian系统上运行得很好的最终解决scheme就是这样,基本上把它转换成一个int,然后使用-gt。

 #!/bin/bash check=`cat /proc/loadavg | sed 's/ / /' | awk '{print $1}'` checkint=${check/\.*} max_load='20'; high_load_log='/var/log/apache2/apache_high_load_restart.log'; apache_init='/etc/init.d/apache2'; if [ $checkint -gt $max_load ]; then echo " check is $checkint and max is $max_load"; $apache_init stop sleep 5; $apache_init restart echo "$(date) : Apache Restart due to excessive load | $check |" >> $high_load_log; else echo "check is $check resolving down to $checkint and max is $max_load - No Action Taken"; fi 

根本的问题是Bash只支持整数算术。 你可以通过使用支持浮点的工具来解决这个问题,方便Awk。

(我也会分解出无用的cat ,注意sed | awk同样是无用的。)

 awk -v max="$max_load" '$1 > max { print "check is " $1 " and max is " max }' /proc/loadavg 

如果你想在一个shell的条件下使用这个,使awk在成功时返回一个零退出码,失败时为非零:

 if ! check=$(awk -v max="$max_load" '($1 > max) { print $1; exit 1 }' /proc/loadavg); then echo " check is $check and max is $max_load"; $apache_init stop sleep 5; $apache_init restart date +"%c : Apache Restart due to load of | $check |" >> $high_load_log; fi