tags:

views:

157

answers:

3

Hi,

why is output empty?

echo "a b c d" | read X Y Z V; echo $X

Thanks.

+5  A: 

I believe it is because echo "a b c d" | read X Y Z V and echo $X are separate statements (I'm not sure of the exact term)? So one doesn't know about the other.

EDIT: Give echo "a b c d" | ( read X Y Z V; echo $X ) a try...

nevets1219
+5  A: 

The issue is that, in order to run the read command with its input redirected from the echo, a new subshell process is spawned. This process reads the values, assigns them to the variables - and then exits; then the second echo command is run. To demonstrate this you can do the second echo and the read both from a subshell:

$ echo "a b c d" | ( read X Y Z V; echo $X )
a
psmears
+3  A: 

In Bash, you can do a couple of different things to accomplish that:

A here string:

read X Y Z V <<< $(echo "a b c d"); echo $X

Process substitution:

read X Y Z V < <(echo "a b c d"); echo $X

A here document with command substitution:

read X Y Z V <<EOF
$(echo "a b c d")
EOF
echo $X

The here document method will also work with POSIX shells in addition to Bash.

If you're reading from a file instead of from the output of another command, it's a little simpler.

Dennis Williamson
Another one you should add: echo a b c d | while read X Y Z V; do echo $X; done
Zan Lynx
@Zan: the problem with that is the same as in the question. After the `while` loop, the values are gone since the while loop creates a subshell.
Dennis Williamson
@Dennis: Yes, but in most cases you only need those variables inside the loop.
Zan Lynx
@Dennis: Thanks for good peaces of code to study.
Vojtech R.
@Zan: I've written many such `while` loops where I needed the values afterwards.
Dennis Williamson