bug-bash
[Top][All Lists]
Advanced

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

Re: document that read built-in can't return zero-length string in the m


From: Greg Wooledge
Subject: Re: document that read built-in can't return zero-length string in the middle of input
Date: Fri, 12 Jan 2024 14:45:06 -0500

On Sat, Jan 13, 2024 at 02:06:08AM +0700, Robert Elz wrote:
>     Date:        Fri, 12 Jan 2024 07:15:35 -0500
>     From:        Greg Wooledge <greg@wooledge.org>
>     Message-ID:  <ZaEtZzH6SkBCkxvj@wooledge.org>
> 
>   | This was one of the things I tested:
> 
> Perhaps intended to, but didn't, or not in this example:
> 
>   | { read -N1; read -r b c; } < <(printf \\nabc); declare -p REPLY a b c
> 
> Rewrite that, correctly for the purpose, as:
> 
>     { read -N1; read -r b c; } < <(printf \\\\\\nabc); declare -p REPLY b c
> 
> or a bit more cleanly as:
> 
>     { read -N1; read -r b c; } < <(printf '\\\nabc'); declare -p REPLY b c

Yes, I made an error there.  Sorry for the confusion.

However, you're testing something slightly different from what I was
testing.  Here's what I originally intended:

unicorn:~$ { read -N1; read -r b c; } < <(printf %s \\nabc); declare -p REPLY b 
c
declare -- REPLY="n"
declare -- b="abc"
declare -- c=""

The important part of the result, for me, is that read -N1 still consumes
two characters of input, and stores one character into the variable.
The stored character is 'n' instead of a newline, after fixing the test.

And here's what you thought I was trying to test:

unicorn:~$ { read -N1; read -r b c; } < <(printf %s $'\\\nabc'); declare -p 
REPLY b c
declare -- REPLY="a"
declare -- b="bc"
declare -- c=""

In this case, read -N1 consumes *three* characters of input, and stores
one character into the variable.  So the character count difference is
even more dramatic.

> ps: the use of process substitution there is just silly, it would work
> just as well, and be easier to understand if written:
> 
>       printf '\\\nabc' | { read -N1; read -r b c; }; declare -p REPLY b c

That requires lastpipe, or moving the declare -p inside the curly braces.

> or    { read -N1; read -r b c; } <<< $'\\\nabc' ; declare -p REPLY b c

<<< unavoidably adds a newline character to the input, which isn't
actually harmful in this case, but isn't what I was trying to test.
I generally go with < <(printf %s ...) when I want to send input that
may not end with a newline.  I simply forgot the %s.

I actually ran several tests before this, which I didn't show in the
previous email.  The first was:

unicorn:~$ { read -r -N1 a b c; } < <(printf abc); declare -p a b c
declare -- a="a"
declare -- b=""
declare -- c=""

I kept making changes to this, ultimately ending up with the test with
the error in it.  I should've started with printf %s in the first place,
but I was lazy.  There's a lesson somewhere in there.

In any case, the important part of this thread is the proposed
documentation change.  My wording may not be ideal, so if you have
any improvement suggestions, feel free to make them.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]