Linux bash: Multiple variable assignment

185.4k Views Asked by At

Does exist in linux bash something similar to the following code in PHP:

list($var1, $var2, $var3) = function_that_returns_a_three_element_array() ;

i.e. you assign in one sentence a corresponding value to 3 different variables.

Let's say I have the bash function myBashFuntion that writes to stdout the string "qwert asdfg zxcvb". Is it possible to do something like:

(var1 var2 var3) = ( `myBashFuntion param1 param2` )

The part at the left of the equal sign is not valid syntax of course. I'm just trying to explain what I'm asking for.

What does work, though, is the following:

array = ( `myBashFuntion param1 param2` )
echo ${array[0]} ${array[1]} ${array[2]}

But an indexed array is not as descriptive as plain variable names.
However, I could just do:

var1 = ${array[0]} ; var2 = ${array[1]} ; var3 = ${array[2]}

But those are 3 more statements that I'd prefer to avoid.

I'm just looking for a shortcut syntax. Is it possible?

6

There are 6 best solutions below

9
On BEST ANSWER

First thing that comes into my mind:

read -r a b c <<<$(echo 1 2 3) ; echo "$a|$b|$c"

output is, unsurprisingly

1|2|3
4
On

Sometimes you have to do something funky. Let's say you want to read from a command (the date example by SDGuero for example) but you want to avoid multiple forks.

read month day year << DATE_COMMAND
 $(date "+%m %d %Y")
DATE_COMMAND
echo $month $day $year

You could also pipe into the read command, but then you'd have to use the variables within a subshell:

day=n/a; month=n/a; year=n/a
date "+%d %m %Y" | { read day month year ; echo $day $month $year; }
echo $day $month $year

results in...

13 08 2013
n/a n/a n/a
2
On

Chapter 5 of the Bash Cookbook by O'Reilly, discusses (at some length) the reasons for the requirement in a variable assignment that there be no spaces around the '=' sign

MYVAR="something"

The explanation has something to do with distinguishing between the name of a command and a variable (where '=' may be a valid argument).

This all seems a little like justifying after the event, but in any case there is no mention of a method of assigning to a list of variables.

4
On

I wanted to assign the values to an array. So, extending Michael Krelin's approach, I did:

read a[{1..3}] <<< $(echo 2 4 6); echo "${a[1]}|${a[2]}|${a[3]}"

which yields:

2|4|6 

as expected.

0
On

let var1=var2=var3=0
or
var1=var2=var3="Default value"

1
On

I think this might help...

In order to break down user inputted dates (mm/dd/yyyy) in my scripts, I store the day, month, and year into an array, and then put the values into separate variables as follows:

DATE_ARRAY=(`echo $2 | sed -e 's/\// /g'`)
MONTH=(`echo ${DATE_ARRAY[0]}`)
DAY=(`echo ${DATE_ARRAY[1]}`)
YEAR=(`echo ${DATE_ARRAY[2]}`)