Problem with `read` command

Problem with `read` command

Post by Roland Krus » Tue, 23 Sep 1997 04:00:00



I'm writing a script, and I want to use the `read' command to
read one line from a command's standard output into a set of
variables. A trivial example illustrating what I want to do:

$ echo hello world | read a b
$ echo $a $b
hello world

Now this works with some shells, but not with others.
(when it doesn't work the variables a and b are not set.)
It generally seems to work with the Korn shell, but
not with bash and /bin/sh.

My guess is that the problem is caused by the `read' command
being executed in a subshell.

Any suggestions how to do this in a portable manner will
be appreciated.

--
Roland Kruse

 
 
 

Problem with `read` command

Post by Hans Georg Schaath » Tue, 23 Sep 1997 04:00:00


On Mon, 22 Sep 1997 12:39:17 +0200, Roland Kruse
: $ echo hello world | read a b
: $ echo $a $b
: hello world

It seems to me that read will run in a subshell, and thus have
its own variables. However this will work:
set `echo hello world`
a=$1
b=$2
echo $a $b

(I have only tested with bash, but it looks like pure sh :-)

--
:-- Hans Georg           --- student of 'Life, the Universe and Everything'


 
 
 

Problem with `read` command

Post by Joachim Huobe » Wed, 24 Sep 1997 04:00:00



> I'm writing a script, and I want to use the `read' command to
> read one line from a command's standard output into a set of
> variables. A trivial example illustrating what I want to do:

> $ echo hello world | read a b
> $ echo $a $b
> hello world

> Now this works with some shells, but not with others.
> (when it doesn't work the variables a and b are not set.)
> It generally seems to work with the Korn shell, but
> not with bash and /bin/sh.

> My guess is that the problem is caused by the `read' command
> being executed in a subshell.

You are right.
The following works and prooves what you guess:

sh, bash, ksh ...
$ echo hallo world | (read a b; echo $a)

Quote:> Any suggestions how to do this in a portable manner will
> be appreciated.

> --
> Roland Kruse

--
____________________________________________________________________
     Joachim Huober
     UNIX System Administrator
     Sony International (Europe) GmbH    Tel: +49-711-5858-566
     Stuttgart Technology Center         Fax: +49-711-58-3185

     70736 Fellbach, Germany    Sony cc:Mail: Huober, Joachim
____________________________________________________________________
 
 
 

Problem with `read` command

Post by Icarus Spar » Wed, 24 Sep 1997 04:00:00




Quote:>I'm writing a script, and I want to use the `read' command to
>read one line from a command's standard output into a set of
>variables. A trivial example illustrating what I want to do:

>$ echo hello world | read a b
>$ echo $a $b
>hello world

>Now this works with some shells, but not with others.
>(when it doesn't work the variables a and b are not set.)
>It generally seems to work with the Korn shell, but
>not with bash and /bin/sh.

>My guess is that the problem is caused by the `read' command
>being executed in a subshell.

Correct.

Quote:>Any suggestions how to do this in a portable manner will
>be appreciated.

Put the whole of the rest of the script into the same subshell ...

echo hello world | { read a b
echo $a $b

Quote:}

Icarus
 
 
 

Problem with `read` command

Post by Donn Ca » Sat, 27 Sep 1997 04:00:00



...
|: Now this works with some shells, but not with others.
|: (when it doesn't work the variables a and b are not set.)
|: It generally seems to work with the Korn shell, but
|: not with bash and /bin/sh.
|:
|: My guess is that the problem is caused by the `read' command
|: being executed in a subshell.
...
| Cool.  'ls | read a b' works in zsh and ksh, but not in bash or
| sh.  I personally don't think it should work anywhere, but that's
| me.

The conventional way to build a pipe, the reader forks the writer.
Hence, if the last item in the pipeline is a shell builtin, it's
natural for it to run in the shell parent process.  Almost obtuse
not to, though it does add to the potential for confusion.

... [recommends "set"]

The parsing done by "set" may even work better than "read", on some
old shells like Ultrix /bin/sh that don't handle spaces properly.

If it suits the actual application better to use "read", write the
data to a temporary file, then use "exec" to redirect I/O for the
shell process itself.  Then you can read in a loop with no redirection,
and no subprocess even in older shells.  The temporary file is quite
efficient, the filesystem will buffer it, so it's not like there's a
lot of overhead in this compared to a pipe.

        Donn Cave, University Computing Services, University of Washington