Determinant
Determinant

Reputation: 4056

How to use the read command in Bash?

When I try to use the read command in Bash like this:

echo hello | read str
echo $str

Nothing echoed, while I think str should contain the string hello. Can anybody please help me understand this behavior?

Upvotes: 63

Views: 117091

Answers (9)

Ege
Ege

Reputation: 541

You don't need echo to use read

 read -p "Guess a Number" NUMBER

Upvotes: -1

JackDR
JackDR

Reputation: 9

I really only use read with "while" and a do loop:

echo "This is NOT a test." | while read -r a b c theRest; do  
echo "$a" "$b" "$theRest"; done  

This is a test.
For what it's worth, I have seen the recommendation to always use -r with the read command in bash.

Upvotes: 0

jpalecek
jpalecek

Reputation: 47770

The read in your script command is fine. However, you execute it in the pipeline, which means it is in a subshell, therefore, the variables it reads to are not visible in the parent shell. You can either

  • move the rest of the script in the subshell, too:

    echo hello | { read str
      echo $str
    }
    
  • or use command substitution to get the value of the variable out of the subshell

    str=$(echo hello)
    echo $str
    

    or a slightly more complicated example (Grabbing the 2nd element of ls)

    str=$(ls | { read a; read a; echo $a; })
    echo $str
    

Upvotes: 62

jxqz
jxqz

Reputation: 117

Another alternative altogether is to use the printf function.

printf -v str 'hello'

Moreover, this construct, combined with the use of single quotes where appropriate, helps to avoid the multi-escape problems of subshells and other forms of interpolative quoting.

Upvotes: -2

RAKK
RAKK

Reputation: 496

To put my two cents here: on KSH, reading as is to a variable will work, because according to the IBM AIX documentation, KSH's read does affects the current shell environment:

The setting of shell variables by the read command affects the current shell execution environment.

This just resulted in me spending a good few minutes figuring out why a one-liner ending with read that I've used a zillion times before on AIX didn't work on Linux... it's because KSH does saves to the current environment and BASH doesn't!

Upvotes: 2

Shizzmo
Shizzmo

Reputation: 16917

Typical usage might look like:

i=0
echo -e "hello1\nhello2\nhello3" | while read str ; do
    echo "$((++i)): $str"
done

and output

1: hello1
2: hello2
3: hello3

Upvotes: 8

glenn jackman
glenn jackman

Reputation: 247162

Other bash alternatives that do not involve a subshell:

read str <<END             # here-doc
hello
END

read str <<< "hello"       # here-string

read str < <(echo hello)   # process substitution

Upvotes: 43

mmrtnt
mmrtnt

Reputation: 392

Do you need the pipe?

echo -ne "$MENU"
read NUMBER

Upvotes: -6

l0b0
l0b0

Reputation: 58958

The value disappears since the read command is run in a separate subshell: Bash FAQ 24

Upvotes: 4

Related Questions