为什么算术表达式的更改会改变bash脚本中ctrl-d的行为?

时间:2014-09-10 09:28:27

标签: bash shell terminal syntax-error

我刚开始在我的学校编写shell脚本,我遇到了一些我找不到答案的问题。

我有一个学校作业来创建一个shell脚本,其中用户应该输入一个数字+输入并重复此操作,直到用户键入ctrl + d,然后程序应该回显总和,程序应该结束。

这是我写的剧本。

sum=0
while [ true ]
do
    read number
    sum=$(($sum+$number))
done

function finish {
    echo "Sum: $sum"
}

trap finish exit

在终端中运行脚本,如下所示:

4
5
summer.sh: line 5: 9+: syntax error: operand expected (error token is "+")
Sum: 9

我读了How can I add numbers in a bash script并且认为我使用了算术表达式(它甚至显示了正确的总和),但是我尝试了同一个问题的另一个建议。我改成了:

sum=$((sum+number))

现在我没有得到语法错误。但我无法通过键入ctrl-d来终止程序。 现在运行代码的示例:

4
5
^D
^C

发生什么事了?为什么脚本中的算术表达式的更改会影响ctrl-d的行为?

2 个答案:

答案 0 :(得分:0)

您的脚本中存在一些问题:

您永远不会检查read的结果。 Ctrl + D 将使read终止,错误代码为1,因此您应该检查:

read number || break

否则,BASH将永远不会退出循环。

然后trap应位于脚本的顶部(这意味着您还必须移动function)。 BASH逐行读取脚本。它没有展望未来。因此,您非常复杂的代码(functionexit)与以下内容完全相同:

echo "Sum: $sum"

尽管在解析函数时没有定义function,但$sum移动到顶部仍然有效,因为BASH会在调用函数时再次读取函数体。那时,sum应该存在且具有正确的值。

答案 1 :(得分:0)

这个脚本应该说明shell运行的问题以及模拟脚本的固定版本所做的事情。

#!/bin/bash

sum=0
while true
do
    read -p 'Number? ' number
    echo "number:$number:"
    echo "\$(($sum+$number))"
    echo "\$(($sum+${number:-0}))"
done

$ ./explain.sh
Number? 5
number:5:
$((0+5))
$((0+5))
Number? 3
number:3:
$((0+3))
$((0+3))
# At this prompt I just hit enter
Number?
number::
$((0+))
$((0+0))
# At this prompt I hit ctrl-d
Number? number::
$((0+))
$((0+0))

在手册页中解释了将零替换为未定义的变量:

  

允许Shell变量作为操作数;参数扩展是   在评估表达式之前执行。在一个   表达式,shell变量也可以通过名称引用   不使用参数扩展语法。一个shell变量   当按名称引用时,null或unset的计算结果为0   不使用参数扩展语法。