7

I understand you can use echo for printing information on the console. But I've tried using return with integers and it didn't work very well for me.

As of

function echo_test() {
    echo 1;
}

function output_echo() {
    local result="$(echo_test)";

    if [[ ${result} == 1 ]]; then
        echo great;
    else
        echo nope;
    fi
}

Output "great", but:

function return_test() {
    return 1;
}

function output_return() {
    local result="$(return_test)";

    if [[ ${result} == 1 ]]; then
        echo great;
    else
        echo nope;
    fi
}

Did not work... and output "nope".

Rafael
  • 1,495
  • 1
  • 14
  • 25
  • I have an example and I would like to understand why the output_return does not have a result as expected. Care to answer that? I did, but if someone doesn't know the answer, or doesn't care to answer, why downvote? – Rafael Aug 08 '18 at 20:46
  • 3
    It's not a dumb question. It's a good question. In the future, you can use `help` to learn about these shell builtins. Like, `help echo` and `help return`. Upvoted. – kojiro Aug 08 '18 at 20:53

1 Answers1

11

You're conflating two separate things: output and exit status.

echo generates output. A command substitution like$(...) captures that output, but if you run a command without it, that output will go to the terminal.

return sets exit status. This is what's used to determine which branch is taken when running if your_function; then ..., or to populate $?.


To see your return_test function actually doing something, you could write:

return_test() {
    return 1;
}

return_test; echo "Exit status is $?"

Also, note that it's possible to do both:

myfunc() {
    echo "This is output"
    return 3
}

myfunc_out=$(myfunc); myfunc_rc=$?
echo "myfunc_out is: $myfunc_out"
echo "myfunc_rc is: $myfunc_rc"

...emits:

myfunc_out is: This is output
myfunc_rc is: 3

One useful idiom is to put an assignment inside an if condition, to branch on exit status while capturing output:

if myfunc_out=$(myfunc); then
  echo "myfunc succeeded (returned 0), with output: [$myfunc_out]"
else rc=$?
  echo "myfunc failed (nonzero return of $rc), with output: [$myfunc_out]"
fi

...which would, in this case, return:

myfunc failed (nonzero return of 3), with output: [This is output]

By the way, you may note that when the above code captures $?, it does so as close as possible to the command whose exit status is being captured, even when this means breaking normal conventions around vertical whitespace. This is intentional, to decrease the likelihood of added logging or other code changes inadvertently modifying $? between the point where it's set and where it's used.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Ah... so the return can only be used for exit status in general? – Rafael Aug 08 '18 at 20:50
  • 1
    `return` only changes a function's exit status; it has no effect on its output. Notably, you can do both: `myfunc() { echo "This is output"; return 3; }` is valid, emitting a string on the function's stdout and also returning with an explicit exit status (notably, output can be any string of characters, whereas exit status can only be numeric -- typically, a single-byte unsigned integer). – Charles Duffy Aug 08 '18 at 20:50
  • Well, that's great then, exactly what I wanted to know. Sorry for the dummy question. Coming from other languages got me wondering about it. – Rafael Aug 08 '18 at 20:51
  • I would disagree that this are duplicated questions since I know how to output a string and this is not what I asked... but, well. Also, using the $ to retrieve the number is a clever idea. I think I should have asked that initially... can I change the question to this? – Rafael Aug 08 '18 at 20:55
  • I saw a similar question for exit and return, but that was not what I wanted to know so I wasn't convinced. I actually wanted to know how to get the return information into a variable anyway. But I still need to test the application of it. – Rafael Aug 08 '18 at 21:01
  • 1
    ...so, I've landed on https://stackoverflow.com/questions/8742783/returning-value-from-called-function-in-a-shell-script -- the questions may not be that *obviously* identical, but questions that are not *obviously* identical on their face is the whole reason we have the duplicate mechanism, so folks can find a canonical instance of their question even when it takes background knowledge to know that they *are* really the same question. I don't think it's possible to read that answer without having this question be resolved as well. – Charles Duffy Aug 08 '18 at 21:01
  • Indeed, good point! – Rafael Aug 08 '18 at 21:03
  • 1
    One aspect that might want to be mentioned is the extremely useful idiom `if var=$(func); then ...`, which assigns the output of `func` to var and checks the output status. – William Pursell Aug 08 '18 at 22:24
  • @WilliamPursell, good call -- I edited to point that out (though as this is community wiki, feel free to contribute directly as well if you choose). – Charles Duffy Aug 08 '18 at 22:31