24

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
  • 3
    Hey why are you guys all using the old, non-POSIX function foo() syntax? You can get better POSIX compatibility with 9 less keypunches.CommentedOct 15, 2015 at 12:44
  • 2
    This syntax is just more familiar to meCommentedOct 15, 2015 at 14:49
  • 3
    @Arthur2e5 primarily because it's easier to type "function" than "[a-zA-Z0-9]+\(\) \{" when searching through the codeCommentedFeb 12, 2019 at 22:47

3 Answers 3

32

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.

    13

    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.CommentedOct 15, 2015 at 12:43
    0

    You can bypass stderr by adding a new file descriptor.

    $ cat hello #!/bin/bash exec 3>&1 function f () { echo hello >&3 echo world } x=$(f) echo "'$x'" $ bash hello hello 'world' $ █ 

    That being said, I'm not an expert in using exec and redirections.

      You must log in to answer this question.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.