2

I'm trying to assign the output of a command to multiple variables, one per output "word". Doing (bash on linux)

echo foo bar baz | read FOO BAR BAZ
echo $FOO $BAR $BAZ

shows only empty strings. Doing

read FOO BAR BAZ < <(echo foo bar barz)
echo $FOO $BAR $BAZ

works as expected. What's wrong here? I thought using a pipe was the most obvious and right way to do that.

4
  • Pipes create shubshells which cannot alter the non-subshell environment. I'll link a duplicate with answers in a minute. Commented Jul 22, 2019 at 10:46
  • Since you already have a working code I guess you just want an explanation of what is hapenning. User pbhd nicely explains it in his post. Piped operations happen in a subshell and therefore any declared variables are accessible only inside it. Commented Jul 22, 2019 at 10:48
  • 1
    This answer explains the problem but is on unix SE. When someone finds a good duplicate on StackOVerflow please link it. I'm sure there is one. Commented Jul 22, 2019 at 10:49
  • 1
    See: mywiki.wooledge.org/BashFAQ/024 Commented Jul 22, 2019 at 12:22

2 Answers 2

4
echo foo bar baz | read FOO BAR BAZ
echo $FOO $BAR $BAZ

In this case it prints nothing. The reason is because pipe creates a subshell in which FOO, BAR and BAZ get values.

echo foo bar baz | { read FOO BAR BAZ ;  echo $FOO $BAR $BAZ ;}

Try this, it will print correct value of all variables. Here, the braces encapsulated the echo command to run in the same subshell in which the variables are read.

read FOO BAR BAZ < <(echo foo bar barz)
echo $FOO $BAR $BAZ

In this case everything happens in the same shell, so you see the output you expect.

Sign up to request clarification or add additional context in comments.

Comments

1

One addition to Mihir's answer -

read a b c <<< "$( echo 1 2 3 )" # a here-string

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.