Bash 脚本函数中的意外输出
Unexpected Output in Bash Script Function
我是 bash 脚本编写的新手,我编写了一个脚本,使用一个函数来计算给定数字的阶乘。该函数适用于零和正数,但它不能为负值提供预期的输出。
这是我的脚本:
#!/bin/bash
# factorial program using a function with while loop
calculate_factorial () {
result=1
current=1
if(( < 0 )); then
echo "The number cannot be negative"
elif(( == 0 )); then
echo "1"
else
while(($current <= )); do
result=$(( result*current ))
current=$(( current+1 ))
done
#print the result
return $result
fi
}
calculate_factorial
echo $result
-8 的输出:
The number cannot be negative
1
本来应该只输出The number cannot be negative
,但我不知道输出的第二行1
来自哪里
如果您能指出我的错误或说明原因,我将不胜感激。
将echo "The number cannot be negative"
更改为result="The number cannot be negative
简短的回答是因为您在函数的开头设置了 result=1
(请注意,由于 result
未声明为局部变量,它是一个全局变量),并且在你的主脚本结束echo $result
。 result
仍然设置为“1”,所以它打印的就是这个。
较长的答案是您误解了如何 return 来自函数的值。一般来说,函数可以产生三种结果:
到 return 数据(在本例中为阶乘值),您应该将其打印到标准输出(又名 stdout,这是默认输出目标)。您可以使用 echo
或任何其他产生输出的命令。 不要为此使用return
命令(见下文)。在 (( == 0 ))
情况下,您正确地执行了此操作。
如果在使用函数时需要捕获输出,可以使用value=$(functname ...args...)
,但在这种情况下看起来你只是想打印它,所以你不需要捕获输出,直接到终端就行了。
到 return 错误或状态消息(如“数字不能为负数”),将其打印到标准错误(又名 stderr)而不是标准输出。您可以使用 >&2
.
将命令的输出重定向到标准错误
到return一个success/failure状态,使用return
命令(0=成功,非零=失败)。这是 all 你应该在 return
命令中 return (同样,脚本中的 exit
值)。如果需要,您可以使用不同的非零值来指示不同的问题,但大多数情况下所有错误都使用 1。
要检查函数的 return 状态,可以将它嵌入到 if
语句之类的东西中,或者立即检查 $?
调用该函数后(它保存最近命令的状态,所以如果你 运行 任何 其他命令,那将替换它)。
另外,double-quote variable and parameter references (e.g. ""
instead of just </code>) to avoid weird parsing. There are a few exceptions, like inside a <code>(( ))
expression. Also, inside (( ))
or other arithmetic contexts, you don't need to use $
to get the value of variables. shellcheck.net it good at pointing out things like this. BTW, in shell syntax, spaces are extremely important delimiters. Using if((
(without a space between) happens to work, but it's a much better to get in the habit of separating elements like if ((
(except, of course, in cases where they're required not to be separated, like var=value
) 的脚本通常是好的。
所以,这是您函数的更正版本:
#!/bin/bash
# factorial program using a function with while loop
calculate_factorial () {
result=1
current=1
if (( < 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 (( == 0 )); then
# Here, we print the result to stdout
echo "1"
# and then return a success status
return 0
else
while (( current <= )); do
result=$(( result*current ))
current=$(( current+1 ))
done
#print the result
echo "$result"
# and then return a success status
return 0
fi
}
calculate_factorial ""
我是 bash 脚本编写的新手,我编写了一个脚本,使用一个函数来计算给定数字的阶乘。该函数适用于零和正数,但它不能为负值提供预期的输出。
这是我的脚本:
#!/bin/bash
# factorial program using a function with while loop
calculate_factorial () {
result=1
current=1
if(( < 0 )); then
echo "The number cannot be negative"
elif(( == 0 )); then
echo "1"
else
while(($current <= )); do
result=$(( result*current ))
current=$(( current+1 ))
done
#print the result
return $result
fi
}
calculate_factorial
echo $result
-8 的输出:
The number cannot be negative
1
本来应该只输出The number cannot be negative
,但我不知道输出的第二行1
来自哪里
如果您能指出我的错误或说明原因,我将不胜感激。
将echo "The number cannot be negative"
更改为result="The number cannot be negative
简短的回答是因为您在函数的开头设置了 result=1
(请注意,由于 result
未声明为局部变量,它是一个全局变量),并且在你的主脚本结束echo $result
。 result
仍然设置为“1”,所以它打印的就是这个。
较长的答案是您误解了如何 return 来自函数的值。一般来说,函数可以产生三种结果:
到 return 数据(在本例中为阶乘值),您应该将其打印到标准输出(又名 stdout,这是默认输出目标)。您可以使用
echo
或任何其他产生输出的命令。 不要为此使用return
命令(见下文)。在(( == 0 ))
情况下,您正确地执行了此操作。如果在使用函数时需要捕获输出,可以使用
value=$(functname ...args...)
,但在这种情况下看起来你只是想打印它,所以你不需要捕获输出,直接到终端就行了。到 return 错误或状态消息(如“数字不能为负数”),将其打印到标准错误(又名 stderr)而不是标准输出。您可以使用
将命令的输出重定向到标准错误>&2
.到return一个success/failure状态,使用
return
命令(0=成功,非零=失败)。这是 all 你应该在return
命令中 return (同样,脚本中的exit
值)。如果需要,您可以使用不同的非零值来指示不同的问题,但大多数情况下所有错误都使用 1。要检查函数的 return 状态,可以将它嵌入到
if
语句之类的东西中,或者立即检查$?
调用该函数后(它保存最近命令的状态,所以如果你 运行 任何 其他命令,那将替换它)。
另外,double-quote variable and parameter references (e.g. ""
instead of just </code>) to avoid weird parsing. There are a few exceptions, like inside a <code>(( ))
expression. Also, inside (( ))
or other arithmetic contexts, you don't need to use $
to get the value of variables. shellcheck.net it good at pointing out things like this. BTW, in shell syntax, spaces are extremely important delimiters. Using if((
(without a space between) happens to work, but it's a much better to get in the habit of separating elements like if ((
(except, of course, in cases where they're required not to be separated, like var=value
) 的脚本通常是好的。
所以,这是您函数的更正版本:
#!/bin/bash
# factorial program using a function with while loop
calculate_factorial () {
result=1
current=1
if (( < 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 (( == 0 )); then
# Here, we print the result to stdout
echo "1"
# and then return a success status
return 0
else
while (( current <= )); do
result=$(( result*current ))
current=$(( current+1 ))
done
#print the result
echo "$result"
# and then return a success status
return 0
fi
}
calculate_factorial ""