Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

read one line with "read" in bash, but without "while"

Tags:

bash

I was trying to understand how "while read" works in bash, and i came accross a behaviour that i can't explain:

root@antec:/# var=old_value
root@antec:/# echo "new_value" | read var && echo $var
old_value
root@antec:/# 

It works fine with "while read":

root@antec:/# var=old_value
root@antec:/# echo "new_value" | while read var; do echo $var; done
new_value
root@antec:/# 

Can someone explain why it does not work when read is used without while ? Moreover, i don't understand how the value of "var" in the main shell can be seen from the allegedly subshell after the pipe ..

Thank you

like image 241
user368507 Avatar asked Jul 28 '11 21:07

user368507


3 Answers

I believe this is precedence problem, with | having higher precedence than &&. First is grouped as:

(echo "new_value" | read var) && echo $var

Second is grouped as:

echo "new_value" | (while read var; do echo $var; done)
like image 134
antlersoft Avatar answered Oct 18 '22 20:10

antlersoft


Why do you think it works in the second case? It doesn't really update var. do echo $var after the line with while and see.

Explanation: whatever comes after | is executed in a subshell that has its own copy of var. The original var is not affected in either case. What is echoed depends on whether echo is called in the same subshell that does read or not.

like image 6
n. 1.8e9-where's-my-share m. Avatar answered Oct 18 '22 19:10

n. 1.8e9-where's-my-share m.


I didn't want to print the variable immediately but use it later on and this works:

var=old_value
read var < <(echo "new_value")
echo $var
> new_value

alternatively:

var=old_value
tmp=$(echo "new_value")
read var <<<"$tmp"
echo $var
> new_value
like image 2
Ronny Lindner Avatar answered Oct 18 '22 18:10

Ronny Lindner