从bash函数返回值


10

我有一个函数,如果数字是有效的十位数,则返回1:

valNum()
{
    flag=1
    if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
        echo "Invalid Number"
        flag=0
    fi
    return $flag
}

它被称为:

if [[ $(valNum $num) -eq 1 ]]; then
      #do something
fi

如果该数字有效,则该功能运行正常,但如果输入无效数字,则显示语法错误。

Answers:


14

@choroba的答案是正确的,但是此示例可能更清晰:

valNum $num
valNumResult=$? # '$?' is the return value of the previous command
if [[ $valNumResult -eq 1 ]]
then
  : # do something
fi

此示例稍长一些(先设置$valNumResult然后查询该值),但更明确地描述会发生什么:valNum()返回一个值,并且可以查询和测试该值。

PS请帮自己一个忙,并返回0true非零的false。这样,在失败的情况下,您可以使用返回值指示“我们为什么失败”。


8

bash中的函数只能返回退出代码。相反,命令替换用于获取命令或功能的标准输出。因此,要检查返回的标志,您不需要替换:

if valNum "$num" ; then
    # ...
fi

但是,要使其正常工作,如果数字有效,则应返回0,否则应返回1(退出代码0表示没有错误)。


我不明白。在tldp.org/LDP/abs/html/complexfunct.html中的示例24.7中,该函数返回的是最大值而不是退出代码。虽然您的建议有效,但我无法理解为什么有效
user2179293 2013年

1
因为你的测试,以找出是否输入是有效的10位整数与否,即真或假,该函数返回0或1。choroba的例子工程,因为if valnum "$num"相当于if valnum "$num" = 0即“如果这是真的”。sh脚本编写的基本经验法则是0 =真/成功,非零=假/错误。
cas

2
顺便说一句,“高级Bash脚本指南”不是一个很好的指南-在很多事情上都是错误的,并鼓励一些不良的脚本实践。mywiki.wooledge.org/BashFAQ上的Bash FAQ 是更好的资源。
cas


您的函数失败,因为它回显了字符串“ Invalid Number”,然后使用if [[ $(valNum $num) -eq 1 ]]
cas

5

您不能从shell函数返回任意结果。您只能返回状态码,该状态码是0到255之间的整数。(虽然您可以将较大的值传递给return,但会以256为模数被截断。)该值必须为0表示成功,而另一个值则表示失败;按照惯例,您应该坚持使用1到125之间的错误代码,因为更高的值具有特殊含义(错误的外部命令126和127被更高的值的信号杀死)。

由于您在此处返回是或否结果,因此状态码是合适的。由于flag似乎表明成功或失败,因此应使用常规值0表示成功,而1表示失败(与您编写的相反)。然后,您可以直接在if语句中使用函数。

valNum ()
{
  local flag=0
  if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
    echo 1>&2 "Invalid Number"
    flag=1
  fi
  return $flag
}
if valNum "$num"; then
  #do something
fi

如果需要区分故障代码,请直接调用该函数。返回后立即在中提供失败代码$?。然后可以使用case语句检查它:

valNum "$num"
case $? in 

如果以后需要使用状态码,请将其保存到另一个变量中,然后再$?由下一个命令覆盖。

valNum "$num"
valNum_status=$?

您写的内容行不通,因为命令替换$(…)扩展到了函数的输出,该代码在您的代码中为错误消息或为空,从不1

如果您需要传递的信息超出状态代码所允许的外壳程序功能范围,则有两种可能性:

  • 在标准输出上打印一些文本,并在命令替换中调用该函数: $(valNum "$num")
  • 分配给函数内的一个或多个变量,然后再读取这些变量。

2

我本人在这方面的结果相互矛盾。这是我的实验结果。首先,关于bash或* nix命令的一些“ 理论 ”:

  • 成功== 0 ...即 无错误状态码)
  • FAIL!= 0 ......一些状态码

例:

if  ls -lt /nonexistantdir
then 
    echo "found"
else
    echo "FAIL"
fi
#
echo
ls -lt /nonexistantdir; echo "status = $?"
echo "status = $?"

输出:

ls: cannot access '/nonexistantdir': No such file or directory
FAIL... 

ls: cannot access '/nonexistantdir': No such file or directory
status = 2

如图所示,该ls命令返回状态码=2。当您尝试有效目录时,状态为零(0)。与几乎所有其他语言不同。

规则#1-使...

  • TRUE == 0
  • 假!= 0

我们必须记住,我们正在Bash 语句中测试错误代码if。我设置常量,或者您可以使用shell truefalse命令。

TRUE=0
FALSE=1

#  valid number function
#
valNum()
{
    flag=$TRUE

    if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
        echo "Invalid Number"
        flag=$FALSE
    fi
    return $flag
}

#    later on ...
#
if validNum Abc 
then
    echo "Lucky number"
else
    echo "Not lucky."
fi

并输出:

Invalid Number
Not lucky.

但是,我建议您使用任何' up-vote '@Gilles,因为他的答案是正确的。我只是想让ePaper面面俱到。

另一件事,就是test命令。看起来像:

[[ some-expression ]]; 

大多数时候。例如:

$ test 1
$ echo "result = $?"
result = 0
$ test 0
$ echo "result = $?"
result = 0

零(0)为true。为什么?好吧,手册页说,当单个参数为NOT-NULL时,它为' true '。

参考资料:

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.