sh's "read" won't take input from pipe

sh's "read" won't take input from pipe

Post by Ken Batem » Sat, 16 May 1992 03:35:37



I'm perplexed.  I can't get read to take input from a pipe.

This works:

        ls -l > $$TEMP
        read TOTALLINE < $$TEMP
        rm $$TEMP
        echo $TOTALLINE

But this doesn't work:
        ls -l | read TOTALLINE
        echo $TOTALLINE

In fact, the second case doesn't modify TOTALLINE at all.  That is,
TOTALLINE maintains its value (if it has one).

Why?  Does it matter that read is an internal command?

------------------------------------------------------

"We are a hedge.  Please move along"  -anonymous ninja

 
 
 

sh's "read" won't take input from pipe

Post by Chet Ram » Sat, 16 May 1992 22:23:06



>But this doesn't work:
>    ls -l | read TOTALLINE
>    echo $TOTALLINE

>In fact, the second case doesn't modify TOTALLINE at all.  That is,
>TOTALLINE maintains its value (if it has one).

sh runs processes that have pipes in or out in subshells.  TOTALLINE
gets set in the subshell, which immediately disappears when that
subshell exits.

Chet
--
``The use of history as therapy means the corruption of history as history.''
        -- Arthur Schlesinger



 
 
 

sh's "read" won't take input from pipe

Post by Hi Ho Silv » Thu, 21 May 1992 08:51:41



$I'm perplexed.  I can't get read to take input from a pipe.
$Why?  Does it matter that read is an internal command?

   Yes, indeed it does.  When you say foo | read bar, the "read bar"
is a separate shell from the one controlling the entire job.  It does,
in fact, read the output of foo into a variable called bar, but the
bar is in the second shell.  It gets run as follows:

/bin/sh (at whose prompt you type 'foo | read bar')
   |
   V
  foo =====(stdout)=====>=====(stdin)===== /bin/sh -c "read bar"

   And of course, the second shell goes away when the command is
finished.

   A quick and inelegant solution is

foo > /tmp/foo$$
read bar < /tmp/foo$$
rm /tmp/foo$$

   One other that I tried on Xenix was

read bar << EOF
`foo`
EOF

   In fact, the output of the command foo does get put into the here
document, but the shell complains that it is unable to read it and
no value is read into bar.  For all I know, this may work on other
*nix flavours, but don't count on its portability if it does.
--
|I know that sometimes my jaw clicks when I eat.  Void where prohibited.|
|Have you seen this boy?  Lust never sleeps.  I say hurl.  Honey, I'm   |
|home. _________________________________________________________________|

 
 
 

sh's "read" won't take input from pipe

Post by Harald.Eik.. » Fri, 22 May 1992 09:10:56



! This works:
!
!       ls -l > $$TEMP
!       read TOTALLINE < $$TEMP
!       rm $$TEMP
!       echo $TOTALLINE
!
! But this doesn't work:
!       ls -l | read TOTALLINE
!       echo $TOTALLINE

Why would you ever want to do such a thing?  Won't

   TOTALLINE=`ls -l`
   echo "$TOTALLINE"

do all you could wish for here?

  ~~harald E.

 
 
 

sh's "read" won't take input from pipe

Post by Harald.Eik.. » Fri, 22 May 1992 09:27:59


Sorry, I guess you meant to read only the 1.st output line from ls -l, so
what about:

   TOTALLINE=`ls -l | head -1`

  ~~harald E.

 
 
 

sh's "read" won't take input from pipe

Post by David W. Tamk » Fri, 22 May 1992 04:39:30




| $I'm perplexed.  I can't get read to take input from a pipe.
| $Why?  Does it matter that read is an internal command?
|
|    Yes, indeed it does.  When you say foo | read bar, the "read bar"
| is a separate shell from the one controlling the entire job.  ...  And of
| course, the second shell goes away when the command is finished.
|
|    A quick and inelegant solution is
|
| foo > /tmp/foo$$
| read bar < /tmp/foo$$
| rm /tmp/foo$$

Ick.  

foo | (read bar
echo $bar)

or even

foo | { read bar
echo $bar ;}

They both worked in sh for me under Dell SVR4 (assuming the foo command
is something that generates some stdout).

David W. Tamkin   Box 59297   Northtown Station, Illinois  60659-0297

 
 
 

sh's "read" won't take input from pipe

Post by Ken Batem » Sat, 23 May 1992 00:08:00



|> ! This works:
|> !
|> ! ls -l > $$TEMP
|> ! read TOTALLINE < $$TEMP
|> ! rm $$TEMP
|> ! echo $TOTALLINE
|> !
|> ! But this doesn't work:
|> ! ls -l | read TOTALLINE
|> ! echo $TOTALLINE
|>
|> Why would you ever want to do such a thing?  Won't
|>
|>    TOTALLINE=`ls -l`
|>    echo "$TOTALLINE"
|>
|> do all you could wish for here?
|>
|>   ~~harald E.

The original example I gave was not representative of the program I was
working on.  It was heavily simplified to what caused the error.  The actual
original program was like this:

IFS=':'
grep -n "^$STRING" * /dev/null | read FILENAME LINENUMBER

Now that I am aware of the problems that method had (namely, the read is
executed in a subshell), I do this:

grep -n "^$STRING" * /dev/null > $$TEMP
IFS=':' ; read FILENAME LINENUMBER < $$TEMP
rm -f $$TEMP

Heaping big steaming hot bowls of thanks to everybody who responded.

------------------------------------------------------

"We are a hedge.  Please move along"  -anonymous ninja