Shell Looking for examples of scripts using READ command

balanga

Son of Beastie

Reaction score: 150
Messages: 3,165

I've been looking for a tutorial or examples of using the READ command in a shell script, but because 'READ' is such a common word I just end up looking at loads of hits which include the word but not in the context I'm looking for.

Does anyone know of any direct links? Or a search string which which has links to READ in the correct context?...
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 8,210
Messages: 31,923

The read command reads from stdin:
Code:
% cat read.sh
#!/bin/sh

while read line
do 
  echo "Read line: $line"
done
Code:
% cat test.txt
This is a line
Another line
Code:
% cat test.txt | ./read.sh
Read line: This is a line
Read line: Another line
 
OP
OP
B

balanga

Son of Beastie

Reaction score: 150
Messages: 3,165

Thanks. I'll have to bookmark that page. I found it previously, but was more comprehensive than what I needed, but it looks like something worth studying at length as time permits.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 8,210
Messages: 31,923

I'll have to bookmark that page.
Definitely recommended. I often use it as a reference, to look up the exact syntax. He has a few other nice tutorials too.
 
OP
OP
B

balanga

Son of Beastie

Reaction score: 150
Messages: 3,165

I was looking through some of the tutorials hoping to get some help with a simple task, but can't find out how to do it....

I have a file which contains four variables seperated by spaces and would like include those variables in a heredoc...

If I use awk I can display those variables as $1 $2 $3 $4, but I can't use these identifiers in my heredoc,

Not sure how to assign those to variables such as abc def ghi jkl... ie how do I assign abc=$1?
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 8,210
Messages: 31,923

Reading four variables:
Code:
dice@maelcum:~/test % cat test2.txt
one two three four
1 2 3 4
uno dos tres quatro
een twee drie vier

dice@maelcum:~/test % cat read.sh
#!/bin/sh

while read a b c d
do
        echo 1: $a 2: $b 3: $c 4: $d

done

dice@maelcum:~/test % cat test2.txt | ./read.sh
1: one 2: two 3: three 4: four
1: 1 2: 2 3: 3 4: 4
1: uno 2: dos 3: tres 4: quatro
1: een 2: twee 3: drie 4: vier
 
OP
OP
B

balanga

Son of Beastie

Reaction score: 150
Messages: 3,165

I thought I had got the hang of it but can't work out why the first example works while the second doesn't....
Code:
wget -q -O- http://free.cccambird.com/freecccam.php | sed -n -e '/Your Free CCcam/s/^.*C:/C:/p' | sed -n -e 's/<.*$//p' > text
read  descr host port user pwd  < text.
echo $descr $host $port $user $pwd.
Code:
wget -q -O- http://free.cccambird.com/freecccam.php | sed -n -e '/Your Free CCcam/s/^.*C:/C:/p' | sed -n -e 's/<.*$//p' | read  descr host port user pwd.
echo $descr $host $port $user $pwd.
 

ralphbsz

Daemon

Reaction score: 1,304
Messages: 2,104

Read the man page for your shell. Somewhere in there, it will say something like: If you write a pipe, every command is executed in a subshell. What happens when you run read in a subshell? Well, let's think about what read does: It reads something from stdin, and sets a variable. A variable of what? Of the shell it is in. Which shell? The innermost subshell. So in the second version, read runs, it sets some variables, and those are promptly forgotten when read ends and the subshell with it.

In the first version, the read is in the main shell, so it sets variables of that shell, which you can then see.

The trick is to not put a naked read into a pipeline, but instead wrap the read in something. Here's my canonical use of read:
# prepare some data
# one or more lines
# each containing for example one word
# and pipe that output into a while command to process the lines
# for example
( echo foo; echo bar; echo blatz ) | \
while read myvar
do
# Now the variable will be set:
echo Hallo myvar is $myvar
done
 

Datapanic

Well-Known Member

Reaction score: 195
Messages: 395

Code:
read -p "Do you really want to hurt me? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
        exit 1
fi
 
OP
OP
B

balanga

Son of Beastie

Reaction score: 150
Messages: 3,165

Read the man page for your shell. Somewhere in there, it will say something like: If you write a pipe, every command is executed in a subshell. What happens when you run read in a subshell? Well, let's think about what read does: It reads something from stdin, and sets a variable. A variable of what? Of the shell it is in. Which shell? The innermost subshell. So in the second version, read runs, it sets some variables, and those are promptly forgotten when read ends and the subshell with it.

In the first version, the read is in the main shell, so it sets variables of that shell, which you can then see.

The trick is to not put a naked read into a pipeline, but instead wrap the read in something. Here's my canonical use of read:
# prepare some data
# one or more lines
# each containing for example one word
# and pipe that output into a while command to process the lines
# for example
( echo foo; echo bar; echo blatz ) | \
while read myvar
do
# Now the variable will be set:
echo Hallo myvar is $myvar
done
Unfortunately I seem to be lacking sufficient brain power to make any sense of this..... I can't understand why I can't get this to work:-


cat text | read descr host port user pwd

but this does work...

read descr host port user pwd < text


text contains:
C: s2.cccambird.com 11700 74873413 cccambird
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 8,210
Messages: 31,923

It's about scope. The pipe spawns a subshell. Variables set in that subshell are not available in the 'parent' shell.

Code:
Shell
    \___ subshell -> variable
Variables are inherited from the parent to the child shells but are not "pushed" back into the parent. As soon as the subshell ends the variables disappear.
 
Top