22

In bash scripts I try to keep my variables local to functions wherever I can and then pass what I need out of functions like bellow

#!/bin/bash

function FUNCTION() {
    local LOCAL="value"
    echo "$LOCAL"   # return this variable
}

GLOBAL=$(FUNCTION)

echo "$GLOBAL"

But is it possible to do this while including the function's own echos so that if the function has it's own messages to output I don't have to catch them in a variable

#!/bin/bash

function FUNCTION() {
    local LOCAL="value"
    echo "$LOCAL"                      # return this variable
    echo "This function is done now"   # do not return this variable
}

GLOBAL=$(FUNCTION)

echo "$GLOBAL"                         # should only echo 'value'
3
  • 2
    Hey why are you guys all using the old, non-POSIX function foo() syntax? You can get better POSIX compatibility with 9 less keypunches. Oct 15, 2015 at 12:44
  • 2
    This syntax is just more familiar to me Oct 15, 2015 at 14:49
  • 3
    @Arthur2e5 primarily because it's easier to type "function" than "[a-zA-Z0-9]+\(\) \{" when searching through the code Feb 12, 2019 at 22:47

2 Answers 2

30

Anything that's printed by the function can be captured if you capture the right output stream. So the easiest way to print something and save some other output is to redirect the superfluous output to standard error:

function FUNCTION() {
    local LOCAL="value"
    echo "$LOCAL"
    echo "This function is done now" >&2
}

Another possibility is to log to a file rather than printing log messages directly, for example using something like this:

log() {
    printf '%s\n' "$@" > my.log
}

That said, Bash functions cannot return variables. The only actual "return" value is the exit code. For this reason (and many others), if you want reliable logging, return values, exception handling and more you'll want to use a different language like Python, Ruby or Java.

12

You can present info messages on standard error:

function FUNCTION() {
    local LOCAL="value"
    echo "$LOCAL"                      # return this variable
    echo "This function is done now" > /dev/stderr  # goes to the screen
}

Some other suggestions are in this Linux Journal article: use global variables (which you mentioned you don't prefer), or pass the name of the variable to return the result in.

1
  • /dev/stderr points to fd 2 and can still be redirected by &>blah or 2>blah. /dev/tty may be better. Oct 15, 2015 at 12:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .