Bash脚本错误。语法错误接近意外令牌

时间:2021-07-10 19:11:38

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="address@domain.com"

VAR=`uptime|awk -F, '{print $4}'|awk '{print $3}'`
OUT=`echo "$VAR $THR" | awk '{if ($1 > $2) print "yes"; else print "no"}'`
if [ "$VAR" == "" ]
then
  # it's within the first 24 hours of uptime
  VAR=`uptime|awk -F, '{print $3}'|awk '{print $3}'`
  OUT=`echo "$VAR $THR" | awk '{if ($1 > $2) 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"

2 个解决方案

#1


2  

Sorry, no offence, but your bash style is terrible!

对不起,无意冒犯,但你的抨击风格很糟糕!

Here's a better version:

这是一个更好的版本:

#!/bin/bash

thr=10
mail="address@domain.com"

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.
  • 使用小写变量名,因为大写变量名被认为是糟糕的bash实践。
  • Don't parse the output of the command uptime using millions of pipes, subshells and awks because it's inefficient, the same information is obtained directly from the file /proc/loadavg, with a read builtin.
  • 不要使用数百万管道、子shell和awks解析命令正常运行时的输出,因为这是低效的,相同的信息直接从文件/proc/loadavg中获取,并使用read内置。
  • Don't use awk to test for inequalities, use bc, it's more efficient (and you don't need a variable $OUT at all).
  • 不要使用awk来测试不等式,使用bc,它更有效(而且根本不需要变量$OUT)。
  • No backticks! Use the $(...) construct instead (easier to read, to nest, and better bash practice).
  • 没有引号的!相反,使用$(…)构造(更容易阅读、嵌套和更好的bash实践)。

I haven't tested the script, just corrected yours as I read it. Please tell me if it works for you.

我没有测试过这个脚本,只是在我读的时候更正了你的脚本。请告诉我它是否适合你。

#2


0  

#!/bin/bash

THR=10
MAIL="address@domain.com"

VAR=`uptime|awk -F, '{print $4}'|awk '{print $3}'`
OUT=`echo "$VAR $THR" | awk '{if ($1 > $2) print "yes"; else print "no"}'`
if [ "$VAR" == "" ]
then
# it's within the first 24 hours of uptime
VAR=`uptime|awk -F, '{print $3}'|awk '{print $3}'`
OUT=`echo "$VAR $THR" | awk '{if ($1 > $2) 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”和-s“服务器负载警报”保持在同一行。

#1


2  

Sorry, no offence, but your bash style is terrible!

对不起,无意冒犯,但你的抨击风格很糟糕!

Here's a better version:

这是一个更好的版本:

#!/bin/bash

thr=10
mail="address@domain.com"

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.
  • 使用小写变量名,因为大写变量名被认为是糟糕的bash实践。
  • Don't parse the output of the command uptime using millions of pipes, subshells and awks because it's inefficient, the same information is obtained directly from the file /proc/loadavg, with a read builtin.
  • 不要使用数百万管道、子shell和awks解析命令正常运行时的输出,因为这是低效的,相同的信息直接从文件/proc/loadavg中获取,并使用read内置。
  • Don't use awk to test for inequalities, use bc, it's more efficient (and you don't need a variable $OUT at all).
  • 不要使用awk来测试不等式,使用bc,它更有效(而且根本不需要变量$OUT)。
  • No backticks! Use the $(...) construct instead (easier to read, to nest, and better bash practice).
  • 没有引号的!相反,使用$(…)构造(更容易阅读、嵌套和更好的bash实践)。

I haven't tested the script, just corrected yours as I read it. Please tell me if it works for you.

我没有测试过这个脚本,只是在我读的时候更正了你的脚本。请告诉我它是否适合你。

#2


0  

#!/bin/bash

THR=10
MAIL="address@domain.com"

VAR=`uptime|awk -F, '{print $4}'|awk '{print $3}'`
OUT=`echo "$VAR $THR" | awk '{if ($1 > $2) print "yes"; else print "no"}'`
if [ "$VAR" == "" ]
then
# it's within the first 24 hours of uptime
VAR=`uptime|awk -F, '{print $3}'|awk '{print $3}'`
OUT=`echo "$VAR $THR" | awk '{if ($1 > $2) 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”和-s“服务器负载警报”保持在同一行。