-1

I have a bash function, whic role is to receive an array, loop thru the array and call another function is_node that check if an node element exist.

If a node element exists `is_node' returns 0, if trows an error returns a number between 1-6, otherwise returns 7 or above.

My issue with is_nodes is even if 'is_node' return 0 will return 7

! return 7, should be triggered if no error appears and no nodes exists

 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
}

pesudeo-code

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
user3541631
  • 3,686
  • 8
  • 48
  • 115
  • Possible duplicate of [Bash conditional based on exit code of command](https://stackoverflow.com/questions/49849957/bash-conditional-based-on-exit-code-of-command) – Julien Lopez Sep 24 '18 at 12:41
  • 3
    `Expanding an array without an index only gives the first element.` (thanks [Shellcheck](https://www.shellcheck.net/)). Also you should definitely store your function return's code in a variable, there's no way the three `$?` correctly reference it. – Aaron Sep 24 '18 at 12:49
  • @JulienLopez is about function $? checks and returns, is different – user3541631 Sep 24 '18 at 13:04
  • 2
    More specifically it will never return 0 because if `[[ $? -gt 0 && $? -lt 7 ]]` is true then it returns 2, if it's false it overwrites `$?` with its return code which will be 1 ; `test` / `[[` is a statement too and writes its return code to `$?`. Not sure whether the second `$?` of your first condition correctly refers to the return code of `is_node`. – Aaron Sep 24 '18 at 13:10
  • seems my understanding of $? related to functions was not correct – user3541631 Sep 24 '18 at 14:32

1 Answers1

2

Here's an attempt at fixing your code.

# 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
}

Part of me wants to refactor the return 0 so you don't need to explicitly compare $? to zero.

        is_node "$node" && return 0

and then correspondingly take out the elif branch. Then the condition in the if can also be reduced to just if [[ "$rc" -lt 7 ]].

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • does 'rc' variable name has a meaning, or is random name ? – user3541631 Sep 25 '18 at 08:36
  • The variable name has no particular significance; you can call it `shirley` if you like. I used it as an abbreviation of "result code" or "return code". – tripleee Sep 25 '18 at 08:53
  • if I do is_node "$node" && is_valid=0 || is_valid=1 , I catch the wrong $? – user3541631 Sep 25 '18 at 11:47
  • Yeah, if you do `if ! success` or `success || something` then the result code of `success` will be lost. The value of `$?` is always the result code of the *immediately* previous command. – tripleee Sep 25 '18 at 12:36