Re: Stupid shell script question about "read"
On Thu, Mar 02, 2006 at 09:19:02AM -0800, David Kirchner wrote:
> On 3/2/06, Kevin B. McCarty <kmccarty@princeton.edu> wrote:
> > Hi list,
> >
> > Could someone tell me why the following works in zsh but not in
> > bash/posh/dash?
> >
> > benjo[3]:~% echo foo bar baz | read a b c
> > benjo[4]:~% echo $a $b $c
> > foo bar baz
> >
> > If I try the same with bash (or other sh-compatible shells), the
> > variables $a $b and $c are unset. From the bash man page:
> > ...
> > So "read" claims to read from the standard input, but it doesn't
> > actually seem to happen when a pipe is involved.
>
> What's happening here is that the pipe is causing a subshell to be
> spawned, which is then parsing the command "read a b c".
>
> http://linuxgazette.net/issue57/tag/1.html
>
> The example he gives, with the < <() syntax, worked in bash, but not
> in Debian or FreeBSD's /bin/sh.
In more recent bashes, the following should work as well
#!/bin/bash
read a b c <<<`echo foo bar baz`
echo $a $b $c
The <<< ("here strings") are an extension of the "here document" syntax,
IOW, the string given after <<< is supplied as stdin to the command.
Then, there's another variant, which is about as ugly as it can get...
It should, however, work with most bourne shell compatible shells:
#!/bin/sh
eval `echo foo bar baz | (read a b c; echo "a='$a';b='$b';c='$c'" )`
echo $a $b $c
To get the variable's values from the subshell back to the main shell,
a shell code fragment is written on stdout, captured with backticks,
and then eval'ed in the main shell... (this is the moment when I
usually switch to some other scripting language -- if not before :)
Cheers,
Almut
Reply to: