[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Stupid shell script question about "read"



On Thursday 02 March 2006 16:23, Kevin B. McCarty 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:
> >  read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars]
> > [-d delim] [name ...]
> >               One  line  is  read  from  the  standard input, or from
> > the file descriptor fd supplied as an argument to the -u option, and 
> > the first word is assigned to the first name, the second word to the
> > second name, and so on, with leftover words and their  interven‐ ing 
> > separators  assigned  to the last name.
>
> So "read" claims to read from the standard input, but it doesn't
> actually seem to happen when a pipe is involved.
> [...]

Each command in the pipeline gets executed in its own subshell and so the 
variables are set there and not passed back to the parent process.  This 
is clear for example when you read about the compound command ( list ):

     (list) list is  executed  in  a  subshell.   Variable
            assignments  and builtin  commands  that  affect
            the  shell's environment do not remain in effect after
            the command completes.  [...]

So this would work:

    $ echo foo bar baz | ( read a b c; echo $a $b $c)
    foo bar baz
    $

Else you can use a 'here document' construct to feed some standard input 
to "read" in the same environment as the shell doing the "read", as for 
example:

    $ read a b c<<END
    > foo bar baz
    > END
    $ echo $a $b $c
    foo bar baz
    $



Ciao.


alfredo



Reply to: