如何在bash脚本的while test中使用函数返回值
这是我的代码摘要。我使用如何在bash脚本的while test中使用函数返回值,bash,Bash,这是我的代码摘要。我使用func中的return\u val与中的“true”之间的比较结果来确定while终止条件。但是回声根本不起作用 #!/bin/bash func(){ a=$1 b=$2 echo $a echo $b if ((a > b)) then return_val="true" else return_val="false" fi } c=1 d=4 whil
func
中的return\u val
与中的“true”
之间的比较结果来确定while终止条件。但是回声根本不起作用
#!/bin/bash
func(){
a=$1
b=$2
echo $a
echo $b
if ((a > b))
then
return_val="true"
else
return_val="false"
fi
}
c=1
d=4
while [[ $(func $c $d) && ("$return_val"!="true") ]]
do
((c++))
done
我宁愿让函数返回一个值
#!/bin/bash
func(){
a=$1
b=$2
echo $a
echo $b
if ((a > b))
then
return 0 # 0 means success
else
return 1 # non-zer0 means failure
fi
}
c=1
d=4
until (func $c $d) #While ! success, do something..
do
((c++))
done
注意:
func$c$d
周围的括号仅用于可读性。实际上不是必需的。因为您想查看echo
命令的输出,所以需要将标准输出与返回(退出)代码分开:
这样,您就可以直接使用函数(前缀为!
以否定测试结果),而无需命令替换,并让其返回(退出)代码驱动的结果,而循环条件(退出代码为0
表示成功,其他任何表示失败)
只需使用!func$c$d
作为条件,func
的标准输出按原样简单打印
附录:指出不需要严格使用显式的return
语句来设置退出代码(但不需要使用test
[1])
((a>b))
本身可以用作函数中的最后一条语句,以隐式设置退出代码:
如果没有显式的return
语句,则是函数的最后一个命令,用于设置其退出代码(在没有exit
语句的情况下,同样适用于脚本)
(…)
将退出代码设置为1
,如果..
的计算结果为0
,则设置为1
(任何非负结果)。如果表达式为真,则诸如A>b
之类的布尔表达式将导致1
,否则将导致0
。因此,((a>b))
本身做了与上述if
语句明确做的相同的事情:
[1] 使用test
或[…]
是符合POSIX的评估条件的方法。除非您的代码必须符合POSIX,否则Bash的[[…]]
和(…)
(用于算术布尔测试)是更好的选择-请参阅强制返回0或1不是正确的方法。您希望返回测试的真实退出状态,而不是强制返回状态。如果。。。然后
block
函数自动返回其退出状态。函数的退出状态是final语句的状态。因此,可以将test
作为func
中的最终语句
#!/usr/bin/env bash
func(){
local a=$1
local b=$2
test $a -lt $b #use exit status directly
}
c=1
d=4
while func $c $d #while c is less than d
do
((c++))
done
@anishane:使用冗余括号会产生创建冗余子shell的效果,因为在bash中括号就是这样做的。总之,IMHO,而func$c$d;do
是完全可读的(至少在您习惯bash之后是这样)。对不起,回音用于调试。我已经了解到,我们应该返回退出状态而不是值。@CodingTheLife:这正是此解决方案的作用:函数的退出代码决定何时退出循环。独立于此,构成条件的命令产生的任何输出都会被传递。如果不需要该输出,请使用/dev/null
抑制标准输出,2>/dev/null
抑制标准输出,并使用&>/dev/null
抑制两者。既然你的问题说“回声不起作用”——考虑到这个解决方案确实“让它们起作用”,你这么说是什么意思?“这不是做这件事的正确方法。”这是夸张——公认的答案是正确的,但不必赘述<代码>((a>b))
本身就可以作为最后一条语句使用-无需使用灵活性和功能较低的测试
内置。为了澄清我之前的评论:您的建议是通过简单地让测试结果隐式地确定函数的退出代码来简化代码,这是一个很好的建议。虽然接受答案中的if
语句实际上是多余的,但它不会屏蔽(…)
表达式的退出代码,因为(…)
本身只设置退出代码0或1。(即使存在掩蔽,也只有在随后测试特定的退出代码集时才有意义,这种情况很少发生;在本例中,而
只关心0与非零)。a
和b
也是不必要的冗长func(){test“$1”-lt“$2”}
的工作原理相同,因为您没有修改参数。
func(){
local a=$1 b=$2
echo "$a" # stdout output
echo "$b"
(( a > b )) # exit code implicitly set to 0, if test *succeeds*, 1 otherwise
}
#!/usr/bin/env bash
func(){
local a=$1
local b=$2
test $a -lt $b #use exit status directly
}
c=1
d=4
while func $c $d #while c is less than d
do
((c++))
done