shell脚本的算术语法错误

时间:2015-12-10 20:43:38

标签: bash shell unix

我正在尝试调用该函数"警告"如果计算为TRUE。我仍然对语法不太满意,想了解如何修复最后一行的一些提示。

    if [ "$noproc" -gt 0 ]; then
    echo "WARNING: NoProc at $noproc for $process processes." >> $log

        elif [ "$max" -ge 11 ]; then 
        [ $(($max - $total)) -lt 6 && [ $idle -le $(($max \* 0.25 | bc -l)) ] ] | warn $total $process $max $idle

我得到的错误:第97行:[:缺少`]'

2 个答案:

答案 0 :(得分:1)

如果您对此问题的标记是正确的并且您真正使用bash(也就是说您的脚本以#!/bin/bash开头,或者如果没有通过shebang启动,则使用bash yourscript而非sh yourscript),你也可以利用它。

# extended bash math syntax
if (( (max - total) < 6 )) && (( idle <= (max / 4) )); then
  warn "$total" "$process" "$max" "$idle"
fi

如果出于某种原因,您不想使用(( )),您仍然可以使用[[ ]],它会为您提供具有自己的扩展语法的测试上下文:

# extended bash test syntax
if [[ $((max - total)) -lt 6 && $idle -le $(bc -l <<<"$max*0.25") ]]; then
  warn "$total" "$process" "$max" "$idle"
fi

...如果你想与POSIX sh兼容,你需要结束测试才能放入shell级别的逻辑AND运算符。

# corrected POSIX-compliant test syntax
if [ "$((max - total))" -lt 6 ] && [ "$idle" -le "$(bc -l <<<"$max*0.25")" ]; then
  warn "$total" "$process" "$max" "$idle"
fi

要了解原因,让我们看看原始命令将如何解析,如果您将(完全错误的)|符号更改为&&而不是:

# Equivalent (longer form) of the original code, with pipe corrected to logical-AND
if [ $(($max - $total)) -lt 6; then
  if [ $idle -le $(($max \* 0.25 | bc -l)) ] ]; then
    warn $total $process $max $idle
  fi
fi

请注意,这是正在运行,作为单个命令[ $(($max - $total)) -lt 6

[不是特殊的shell语法 - 它只是一个命令。在旧壳中它实际上是/usr/bin/[;今天,内置了[,但除了执行速度更快之外,它的行为与执行旧的外部命令时的行为完全相同。

[命令期望传递]作为其最后一个参数,因为在]之后没有-lt 6,您会收到语法错误并退出。

同样,您的代码将(如果第一个命令成功)运行[ $idle -le $(($max \* 0.25 | bc -l)) ] ]。在这里,您有一个[命令在最后传递两个 ];它根本不知道如何处理第二个。

答案 1 :(得分:0)

  • 您无法嵌套[次调用。即使你可以,a && (b) === a && b在逻辑上。
  • 您不能在算术扩展中使用命令。
  • Bash的[[[更安全。
  • 使用更多报价™。

结果:

[[ "$(($max - $total))" -lt 6 ]] && [[ "$idle" -le "$(bc -l <<< "$max * 0.25")" ]] | warn "$total $process $max $idle"