1

I know that you use a echo "return-value" and $(my_function) to call functions in the bash.

But maybe there is an extension to bash, so that you can return two values?

It would be really great, if I could use this pattern (like in Go):

function my_function()
    ....
    return "foo", 0

Usage of the function:

value, err = my_function()
U. Windl
  • 3,480
  • 26
  • 54
guettli
  • 25,042
  • 81
  • 346
  • 663
  • You could `echo` those values with a delimiter and 'split' then after calling the function. Or just globals. – 0stone0 Apr 28 '23 at 08:47
  • 1
    You can use multiple file descriptors, but you'll find this bothersome if you wan't to avoid using files or calling the function multiple times. Here's an example : https://ideone.com/logDyP – Aaron Apr 28 '23 at 08:47
  • Functions in bash don't have a return value. Actually, the word _function_ is a misnomer and they should have better be called _subroutines_. The `return` statement just sets an exit code which the caller can pick up using the variable `$?`. Since you should reasonably only use values from 0 to 126 for an exit code, this mechanism is at best suitable for communicating back very small non-negative integers. – user1934428 Apr 28 '23 at 09:01
  • Instead you use some differenct mechanism for passing information from a function to the caller: Write the data to a file which is then read by the caller, write data to stdout and/or stderr, use global shell variables, use namerefs, just to give some examples. – user1934428 Apr 28 '23 at 09:04

1 Answers1

4

With recent bash you can use namerefs and pass your function the names of the variables to assign: my_function value err. Example:

$ my_function() {
  local -n v="$1" e="$2"
  v="foo bar"
  e="baz qux"
}
$ my_function value err
$ echo "$value"
foo bar
$ echo "$err"
baz qux

You can also design your function to print two string values on the standard output separated by a custom separator that cannot be found in the string values (for instance a newline) and assign this to an array:

$ my_function() {
  local v e
  v="foo bar"
  e="baz qux"
  printf '%s\n%s' "$v" "$e"
}
$ IFS=$'\n' arr=($(my_function))
$ echo "${arr[0]}"
foo bar
$ echo "${arr[1]}"
baz qux

And again with namerefs you can have kind of named aliases for the array elements:

$ declare -n value=arr[0] err=arr[1]
$ echo "$value"
foo bar
$ echo "$err"
baz qux
Renaud Pacalet
  • 25,260
  • 3
  • 34
  • 51
  • Great! But I struggle to find the official docs about this great feature. – guettli Apr 28 '23 at 10:40
  • 1
    Just type `man bash` and read the `PARAMETERS` section. Or visit [the bash documentation](https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameters) and search `nameref`. – Renaud Pacalet Apr 28 '23 at 10:48