我是bash脚本的新手,我编写了一个脚本,使用一个函数来计算给定数字的阶乘。该函数可以很好地处理零和正数,但不能给出负值的预期输出。
下面是我的脚本:#!/bin/bash
# factorial program using a function with while loop
calculate_factorial () {
result=1
current=1
if(( $1 < 0 )); then
echo "The number cannot be negative"
elif(( $1 == 0 )); then
echo "1"
else
while(($current <= $1)); do
result=$(( result*current ))
current=$(( current+1 ))
done
#print the result
return $result
fi
}
calculate_factorial $1
echo $result
-8的输出:
The number cannot be negative
1
它应该只输出The number cannot be negative
,但我不知道1
在输出的第二行来自哪里。
如果我有任何错误,请您指出或解释原因,我将不胜感激。
简短的回答是,这是因为您在函数的开头设置了result=1
(请注意,由于result
没有声明为局部变量,它是一个全局变量),并在主脚本的末尾设置了echo $result
。result
仍然被设置为"1",所以这就是它打印的内容。
更长的答案是你误解了如何从函数返回值。一般来说,函数可以产生三种结果:
-
要返回数据(在本例中是阶乘值),应该将其打印到标准输出(也称为stdout,这是默认输出目标)。您可以使用
echo
或任何其他产生输出的命令。要而不是使用return
命令(见下文)。在(( $1 == 0 ))
的情况下,这样做是正确的。如果在使用该函数时需要捕获输出,可以使用
value=$(functname ...args...)
,但在这种情况下,看起来您只想打印它,因此不需要捕获输出,只需让它直接进入终端。 -
要返回错误或状态消息(如"数字不能为负"),将其打印到标准错误(又名stderr)而不是标准输出。您可以使用
>&2
将命令的输出重定向到标准错误。 -
返回成功/失败状态,使用
return
命令(0=成功,非零=失败)。这是您应该在return
命令中返回的所有(类似地,脚本中的exit
值)。如果您愿意,可以使用不同的非零值来表示不同的问题,但大多数情况下只使用1来表示所有错误。要检查函数的返回状态,要么将其嵌入
if
语句中,要么在调用函数后立即检查$?
(它保存最近命令的状态,因此如果您运行任何其他命令,它将替换它)。
此外,通常良好的脚本卫生是双引号变量和参数引用(例如"$1"
而不仅仅是$1
),以避免奇怪的解析。也有一些例外,比如在(( ))
表达式中。此外,在(( ))
或其他算术上下文中,不需要使用$
来获取变量的值。Shellcheck.net擅长指出这类问题。顺便说一句,在shell语法中,空格是非常重要的分隔符。使用if((
(中间没有空格)是可行的,但是养成像if ((
这样分隔元素的习惯要好得多(当然,除非需要分隔而不是,比如var=value
)。
所以,这是你的函数的更正版本:
#!/bin/bash
# factorial program using a function with while loop
calculate_factorial () {
result=1
current=1
if (( $1 < 0 )); then
# Here, we print an error message to stderr
echo "The number cannot be negative" >&2
# and then return an error status
return 1
elif (( $1 == 0 )); then
# Here, we print the result to stdout
echo "1"
# and then return a success status
return 0
else
while (( current <= $1 )); do
result=$(( result*current ))
current=$(( current+1 ))
done
#print the result
echo "$result"
# and then return a success status
return 0
fi
}
calculate_factorial "$1"
将echo "The number cannot be negative"
更改为result="The number cannot be negative