Say I have a loop that goes through a file line-by-line via read. I would like to have both the original line, and the line split into different variables, which read does nicely. However, I can't seem to echo a variable, pipe it to read, and have the variables populated. Here's a base case:

echo "a b c d e f g" | read line
echo "Read obtained: $line"

The result:

Read obtained:

How can I make read do what I want? Or: Why am I wrong to ask read to do this, and what should I do instead?

marked as duplicate by Wildcard, Scott, Kusalananda bash Sep 9 '17 at 7:24

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Pipelines create a subshell and read is a built-in, so it hasn't actually been executed in your top level script/shell. And also, don't use a shell loop to process text! – Wildcard Sep 9 '17 at 3:48
  • Even if read were to be able to assign to a variable in the outer scope, your snippet of code is pretty much (but TBH not exactly) the same as a simple assignment: line="a b c d e f g". – roaima Sep 9 '17 at 9:13
  • I understand. I was only presenting a minimal case to demonstrate. – Matthew Curry Sep 9 '17 at 23:52

You can tell read read from pipeline as follows; Original answer by @yardena on SO

echo "a b c d e f g" | { read line; echo line=$line; }
  • Try echo "$line" on the next line, i.e. outside your curly braces, to see the problem – roaima Sep 9 '17 at 12:56

the problem is scope. the variable has no value outside the subshell created by the pipe. Instead:

while read line; do echo "read obtained: ${line}"; done < <(echo "a b c d e f g")

use a loop however you want to. if you want to process text with one, do it. -C

Not the answer you're looking for? Browse other questions tagged or ask your own question.