2

I have looked at various ways on here handle function return values within BASH if-then statements, but none seem to work. Here is what I've got

 function is_cloned()
 {
      if [ -d $DIR_NAME ]
      then
           return $SUCCESS
      fi
      return $FAILURE
 }

It will work if I call it on its own and check the return value like:

 is_cloned
 retval=$?
 if [ $retval -eq $FAILURE ] 
 then
      ...
 fi

How can I use the function call within the if statement? Or is there no way at all to take advantage of the return values?

basil
  • 690
  • 2
  • 11
  • 30
  • 1
    `if` is always checking the return value of a command. Note that the `[` *is* a command. Try `help [` to see. Instead of `[` you can use any command or function, like this: `if my_cmd ; then do this ; else do that ; ` – hek2mgl Oct 11 '17 at 17:22
  • 1
    Unless you have some very specific values of `SUCCESS` and `FAILURE` that you are using in place of `0` and `1`, just use `is_cloned () { [ -d "$DIR_NAME" ]; }`. – chepner Oct 11 '17 at 17:27

1 Answers1

11

if statements in Bash can use the exit code of functions directly. So you can write like this:

if is_cloned
then
    echo success
fi

If you want to check for failure, as in your posted code, you could use the ! operator:

if ! is_cloned
then
    echo failure
fi

By the way, your is_cloned function too can rely more on exit codes, you can write like this:

is_cloned() {
    [ -d "$DIR_NAME" ]
}

This works, because the exit code of a function is the exit code of the last executed command, and the exit code of [ ... ] is 0 if successful, non-zero otherwise (= failure).

Also remember to double-quote variable names used as command arguments, as I did DIR_NAME here.

janos
  • 120,954
  • 29
  • 226
  • 236
  • 1
    Sort of defeats the point of the function at all, may as well just test DIR_NAME. – 123 Oct 11 '17 at 17:23
  • 2
    @123 Just because it's simple, that doesn't mean it's useless. The function encapsulates a specific logic. If the logic needs to be improved later, it can be done by modifying just the function, leaving the rest of the program alone. – janos Oct 11 '17 at 17:25
  • Will the first methodology you listed even rely on error codes or will it just execute that code if the function call doesn't exit the script? – basil Oct 11 '17 at 17:25
  • @basil It's called "exit code", not "error code". The `if is_cloned` statement uses the exit code of the `is_cloned` function. The exit code can be in an explicit `return` statement, or it's the exit code of the last executed command. Does that answer your question? – janos Oct 11 '17 at 17:28
  • 1
    @janos Encapsulation for the sake of it unnecessarily increases code complexity. – 123 Oct 11 '17 at 17:31
  • 2
    @123, ...there's a judgment call to be made there, to be sure. *However*, if `is_cloned` makes it more obvious to a reader what the intent behind a statement is than it would otherwise be from context, that's adding value in and of itself. (Whether that value is sufficient... again, we're in contextually-dependent judgment-call territory) – Charles Duffy Oct 11 '17 at 17:33
  • 1
    @123 I definitely prefer to read `if is_cloned` than `if [ -d DIR_NAME ]` when reading a main program. If I'm new to the code it's far easier to get what the code is doing and in addition it is self explaining without a comment. If I'm interested in how the program decides whether *something* is cloned or not I just need to look at the implementation of the function. To be honest, besides some trivial shell scripts, there are very few to no reasons to not encapsulate `is_cloned` (for example). – hek2mgl Oct 11 '17 at 18:07
  • @123 If the name of the function would be `dir_exists`, I would agree that it would be unnecessary encapsulation. – hek2mgl Oct 11 '17 at 18:20