我刚开始在我的学校编写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的行为?
答案 0 :(得分:0)
您的脚本中存在一些问题:
您永远不会检查read
的结果。 Ctrl + D 将使read
终止,错误代码为1,因此您应该检查:
read number || break
否则,BASH将永远不会退出循环。
然后trap
应位于脚本的顶部(这意味着您还必须移动function
)。 BASH逐行读取脚本。它没有展望未来。因此,您非常复杂的代码(function
至exit
)与以下内容完全相同:
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 不使用参数扩展语法。