Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Oct 2018 16:35:11 +0200
From:      Martin Beran <martin@mber.cz>
To:        freebsd-hackers@freebsd.org
Subject:   Re: shell read built-in
Message-ID:  <f5dc4a0d-b00e-c715-906c-7599f8188d54@mber.cz>
In-Reply-To: <4cd38621-7387-6302-437e-b8fda3fbe1cd@yuripv.net>
References:  <2fff355e-a729-d5d3-8199-f2bbba80c112@grosbein.net> <4ad1ea37-4714-a104-89a2-d7aef70d0f89@yuripv.net> <4cd38621-7387-6302-437e-b8fda3fbe1cd@yuripv.net>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?f5dc4a0d-b00e-c715-906c-7599f8188d54>