How to get the output of a shell function without forking a sub shell?

An ugly solution is to temporarily replace echo so that it sets a global variable, which you can access from your function:

func () {
  echo () {
    result="$@"
  }
  result=
  hello
  unset -f echo
  echo "Result is $result"
}

I agree it's nasty, but avoids the subshell.


You can make the caller pass in a variable name to hold the output value and then create a global variable with that name inside the function, like this:

myfunc() { declare -g $1="hello"; }

Then call it as:

myfunc mystring
echo "$mystring world" # gives "hello world"

So, your functions can be re-written as:

hello() {
    declare -g $1="Hello"
}

func() {
    hello Var
    echo "${Var/e/E} world"
}

The only limitation is that variables used for holding the output values can't be local.


Related post which talks about using namerefs:

  • How to return an array in bash without using globals?

How about using a file descriptor and a Bash here string?

hello () {
    exec 3<<<"Hello"
}

func () {
    local Var
    exec 3>&-
    hello && read Var <&3
    echo "${Var/e/E} world"
    exec 3>&-
}

func

Tags:

Shell

Bash

Zsh