【问题标题】:Conditional return with default return not working默认返回的条件返回不起作用
【发布时间】:2018-09-24 12:35:42
【问题描述】:

我有一个 bash 函数,它的作用是接收一个数组,遍历数组并调用另一个函数 is_node 来检查节点元素是否存在。

如果节点元素存在`is_node'返回0,如果发生错误返回1-6之间的数字,否则返回7或以上。

我对@9​​87654324@ 的问题是即使'is_node'return 0return 7

!返回7,如果没有出现错误且不存在节点则应该触发

 function is_nodes() { 
    local arr=("$@")    

    for node in ${arr}
    do
        is_node $node 
        if [[  $? -gt 0 && $? -lt 7  ]]
        then
            return 2
        elif [[ $? -eq 0 ]]
        then
            return 0
        fi  
    done
    # default
    return 7
}

伪代码

is_nodes receive an array (node1 node2 node3)
loop
  is_node node1 triggers an error ?; no go further
  is_node node1 exists(return 0) ?; no continue   
  is_node node2 triggers an error ?; no go further
  is_node node2 exists(return 0) ?; yes get out of the function and return 0

【问题讨论】:

  • Expanding an array without an index only gives the first element.(感谢Shellcheck)。另外,您绝对应该将函数返回的代码存储在变量中,三个$? 无法正确引用它。
  • @JulienLopez 是关于函数 $?支票和退货,是不一样的
  • 更具体地说,它永远不会返回 0,因为如果 [[ $? -gt 0 && $? -lt 7 ]] 为真则返回 2,如果为假则覆盖 $?,其返回码将为 1; test / [[ 也是一个语句,并将其返回码写入$?。不确定您的第一个条件的第二个$? 是否正确引用了is_node 的返回码。
  • 看来我对$的理解?相关功能不正确

标签: bash


【解决方案1】:

这是修复代码的尝试。

# Don't use Bash-only keyword function
is_nodes() {
    # New variable
    local rc
    # No array needed, just loop over arguments
    for node in "$@"
    do
        # Take care to properly quote argument
        is_node "$node"
        # Capture result
        rc=$?
        if [[ "$rc" -gt 0 && "$rc" -lt 7  ]]
        then
            return 2
        elif [[ "$rc" -eq 0 ]]
        then
            return 0
        fi  
    done
    # default
    return 7
}

我的一部分想要重构return 0,因此您无需将$? 显式比较为零。

        is_node "$node" && return 0

然后对应取出elif分支。那么if中的条件也可以简化为if [[ "$rc" -lt 7 ]]

【讨论】:

  • 'rc'变量名是否有意义,还是随机名?
  • 变量名没有特别意义;如果你愿意,你可以叫它shirley。我用它作为“结果代码”或“返回代码”的缩写。
  • 如果我这样做 is_node "$node" && is_valid=0 || is_valid=1 ,我抓错了 $?
  • 是的,如果您执行if ! successsuccess || something,那么success 的结果代码将会丢失。 $? 的值始终是 immediately 上一条命令的结果代码。
最近更新 更多