idioms for returning multiple values in shell scripting

In the special case where your values never contain spaces, this read trick can be a simple solution:

get_vars () {
  #...
  echo "value1" "value2"
}

read var1 var2 < <(get_vars)
echo "var1='$var1', var2='$var2'"

But of course, it breaks as soon as there is a space in one of the values. You could modify IFS and use a special separator in your function's echo, but then the result is not really simpler than the other suggested solutions.


Yet another way:

function get_tuple()
{
  echo -e "Value1\nValue2"
}

IFS=$'\n' read -d '' -ra VALUES < <(get_tuple)
echo "${VALUES[0]}" # Value1
echo "${VALUES[1]}" # Value2

Much as I love shell, it's probably the case that as soon as you're throwing arbitrary structured data around, Unix bourne/posix shell is not the right choice.

If there are characters which do not occur inside fields, then separate with one of those. The classic example is /etc/passwd, /etc/group and various other files which use a colon as a field separator.

If using a shell which can handle a NUL character inside strings, then joining on the NUL and separating on it (via $IFS or whatever) can work well. But several common shells, including bash, break on NUL. A test would be an old .sig of mine:

foo=$'a\0b'; [ ${#foo} -eq 3 ] && echo "$0 rocks"

Even if that would work for you, you've just reached one of the warning signs that it's time to switch to a more structured language (Python, Perl, Ruby, Lua, Javascript ... pick your preferred poison). Your code is likely to become hard to maintain; even if you can, there's a smaller pool of people who'll understand it well enough to maintain it.


This question was posted 5 years ago, but I have some interesting answer to post. I have just started learning bash, and I also encounter to the same problem as you did. I think this trick might be helpful:

#!/bin/sh

foo=""
bar=""

my_func(){
    echo 'foo="a"; bar="b"'
}

eval $(my_func)
echo $foo $bar
# result: a b

This trick is also useful for solving a problem when a child process can not send back a value to its parent process.

Tags:

Shell

Idioms