Bash 脚本错误。意外标记附近的语法错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/13699240/
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
Bash script error. Syntax error near unexpected token
提问by Adam
I'm trying to work through a script to email me a notification if the load is too high on our server. I found a good one but it's giving me and error when I run it, and I can't see why.
如果我们的服务器负载过高,我正在尝试通过脚本向我发送电子邮件通知。我找到了一个很好的,但是当我运行它时它给了我和错误,我不明白为什么。
Running the code below gives the error:
运行下面的代码会出现错误:
line 13: syntax error near unexpected token `fi'
第 13 行:意外标记“fi”附近的语法错误
I thought I had to laid out correctly though. Thanks!
不过,我认为我必须正确布局。谢谢!
#!/bin/bash
THR=10
MAIL="[email protected]"
VAR=`uptime|awk -F, '{print }'|awk '{print }'`
OUT=`echo "$VAR $THR" | awk '{if ( > ) print "yes"; else print "no"}'`
if [ "$VAR" == "" ]
then
  # it's within the first 24 hours of uptime
  VAR=`uptime|awk -F, '{print }'|awk '{print }'`
  OUT=`echo "$VAR $THR" | awk '{if ( > ) print "yes"; else print "no"}'`
fi
if [ "$OUT" == "yes" ]
then
  echo "The current load $VAR is greater than the threshold $THR" | mail $MAIL
  -s "Server Load Alert"
  echo "Alert generated because $VAR is greater than $THR"
else
  echo "No alert as $VAR > $THR"
fi
echo "load = $VAR"
回答by gniourf_gniourf
Sorry, no offence, but your bash style is terrible!
对不起,没有冒犯,但你的 bash 风格很糟糕!
Here's a better version:
这是一个更好的版本:
#!/bin/bash
thr=10
mail="[email protected]"
read var _ < /proc/loadavg
if (( $(bc -l <<< "$var>$thr") )); then
    echo "The current load $var is greater than the threshold $thr" | mail "$mail" -s "Server Load Alert"
    echo "Alert generated because $var is greater than $thr"
else
    echo "No alert as $var <= $thr"
fi
echo "load = $var"
The changes are the following:
变化如下:
- Use lower case variable names, as upper case variable names are considered bad bash practice.
- Don't parse the output of the command uptimeusing millions of pipes, subshells andawks because it's inefficient, the same information is obtained directly from the file/proc/loadavg, with areadbuiltin.
- Don't use awkto test for inequalities, usebc, it's more efficient (and you don't need a variable$OUTat all).
- No backticks! Use the $(...)construct instead (easier to read, to nest, and better bash practice).
- 使用小写变量名,因为大写变量名被认为是不好的 bash 实践。
- 不要uptime使用数以百万计的管道、子shell 和awks解析命令的输出,因为它效率低下,相同的信息是直接从文件中获取的/proc/loadavg,带有read内置函数。
- 不要awk用于测试不等式,使用bc,它更有效(并且您根本不需要变量$OUT)。
- 没有反引号!改用$(...)构造(更容易阅读、嵌套和更好的 bash 练习)。
I haven't tested the script, just corrected yours as I read it. Please tell me if it works for you.
我还没有测试脚本,只是在我阅读时更正了你的脚本。请告诉我它是否适合您。
回答by Arnestig
#!/bin/bash
THR=10
MAIL="[email protected]"
VAR=`uptime|awk -F, '{print }'|awk '{print }'`
OUT=`echo "$VAR $THR" | awk '{if ( > ) print "yes"; else print "no"}'`
if [ "$VAR" == "" ]
then
# it's within the first 24 hours of uptime
VAR=`uptime|awk -F, '{print }'|awk '{print }'`
OUT=`echo "$VAR $THR" | awk '{if ( > ) print "yes"; else print "no"}'`
fi
if [ "$OUT" == "yes" ]
then
echo "The current load $VAR is greater than the threshold $THR" | mail $MAIL -s "Server Load Alert"
echo "Alert generated because $VAR is greater than $THR"
else
echo "No alert as $VAR > $THR"
fi
echo "load = $VAR"
This works for me. I changed so that "mail $MAIL" and -s "Server Load Alert" keeps on the same row.
这对我有用。我进行了更改,以便“mail $MAIL”和-s“服务器负载警报”保持在同一行。

