shell read built-in

Martin Beran martin at mber.cz
Mon Oct 22 14:35:17 UTC 2018


On 10/22/18 1:32 PM, Yuri Pankov wrote:

> BTW, it looks like last line is still parsed despite not having \n, so
> you could workaround it using something like (yes, looks ugly):
> 
> $ printf "foo bar\n" | (while read a b; do printf "%s %s\n" $a $b; done;
> if test -n "$a$b"; then printf "%s %s\n" $a $b; fi)
> foo bar
> $ printf "foo bar" | (while read a b; do printf "%s %s\n" $a $b; done;
> if test -n "$a$b"; then printf "%s %s\n" $a $b; fi)
> foo bar

If code in the while loop is more complex and you do not want to repeat
it twice or define a shell function for it, you can use:

while { read l; e=$?; [ $e = 0 ]; } || [ -n "$l" ]; do
    : any code that processes $l
    [ $e = 0 ] || break
done;

The condition tests that either read returns 0 (a line terminated by
'\n') or puts a nonempty value to $l (the last line not terminated by
'\n'). The break command eliminates further read after EOF (nonzero
return), because on a terminal, after EOF (pressing ^D), read returns
false once. When called again, it continues reading from the terminal
until the next ^D.

-- 
Martin Beran


More information about the freebsd-hackers mailing list