3

Let's say I have a command my_command which I am sure outputs three lines like

line 1
line 2
line 3

and I want to store the three lines into three variables $x, $y, $z. How can I accomplish this in bash?

nullUser
  • 1,601
  • 1
  • 12
  • 29
  • possible duplicate of [How do I assign the output of a command into an array?](http://stackoverflow.com/questions/9449417/how-do-i-assign-the-output-of-a-command-into-an-array) – Whymarrh Jul 23 '14 at 01:17
  • I would prefer to keep the names x,y,z as they are quantities that have meaning and increase the readability of the code. – nullUser Jul 23 '14 at 01:21
  • Well that's why is a _possible_ duplicate. As well, you could just alias the array values. – Whymarrh Jul 23 '14 at 01:22

2 Answers2

4
for name in x y z; do
    read $name
done < <(my_command)

This uses process substitution so that the read commands are not executed in a subshell and the resulting variables are available after the loop completes. The variable name is used to hold the names of the variables to set; $name expands to the name of the variable that read sets, so after the loop you have three variables x, y, and z that hold each of the three lines of your output.

You can also use a here document instead of process substitution:

for name in x y z; do
    read $name
done <<EOF
$(my_command)
EOF
chepner
  • 497,756
  • 71
  • 530
  • 681
4

And here's another:

IFS=$'\n' read -d '' x y z __ < <(my_command)

With -d '' it sets the delimiter to '\0' and makes read read the whole input in one instance, and not just a single line. IFS=$'\n' sets newline (\n) as the separator for each value. __ is optional and gathers any extra input besides the first 3 lines.

From help read:

Reads a single line from the standard input, or from file descriptor FD if the -u option is supplied. The line is split into fields as with word splitting, and the first word is assigned to the first NAME, the second word to the second NAME, and so on, with any leftover words assigned to the last NAME. Only the characters found in $IFS are recognized as word delimiters.

-d delim     continue until the first character of DELIM is read, rather than newline

konsolebox
  • 72,135
  • 12
  • 99
  • 105