bug-bash
[Top][All Lists]
Advanced

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

Re: Questions to bash "read" builtin functionality (and supposed problem


From: Pierre Gaston
Subject: Re: Questions to bash "read" builtin functionality (and supposed problem with while).
Date: Fri, 18 Jan 2013 13:56:20 +0200

On Fri, Jan 18, 2013 at 1:38 PM, Linus Swälas <linus.swalas@gmail.com> wrote:
> On Fri, Jan 18, 2013 at 6:57 AM, Pierre Gaston <pierre.gaston@gmail.com> 
> wrote:
>>
>> On Thu, Jan 17, 2013 at 4:24 PM, Linus Swälas <linus.swalas@gmail.com>
>> wrote:
>>>
>>> I have a similar problem to report as Fiedler Roman regarding read and
>>> also
>>> another problem regarding while. Maybe the while case is intended behavior
>>> though. =)
>
>>> # while can't handle nulls, this doesn't work:
>>> # while read -d \x00 cfg
>>> # while this does work:
>>> # read -d \x00 test < <(find . -name some_file -print0) ; echo $test
>>>
>>
>> \x00 doesn't mean anything special for bash  it's just an "x" followed by 2
>> zeros (echo, printf can interpret it and it has a special meaning inside
>> $'')
>> Even if it did, you cannot really pass the null byte as an argument, bash
>> uses null delimited string so the best you can do is to pass the empty
>> string:
>> read -d ''
>> The good thing is that it works to read null delimited input! you need a bit
>> more work to be fully safe though:
>> while IFS= read -rd ''; do ..... done < <(find ... -print0)
>
> Yes, I see that now, I managed to fool myself with vim's syntax highlighting. 
> =)
> In combination with the fact that I only find one file with no x in
> it's name, and that
> read then never can find it's delimiter, x in this case, gives the
> appearance of not
> being able to handle nulls.
> That links back to the real question though, one that got overlooked,
> that read seem
> to discard input.
> Cut from the earlier example, with superfluous comments etc removed:
>
>         while :
>         do
>                 # Now, read from the console, with \n as delimiter.
>                 read -t 2 data
>                 ret=$?
>
>                 # Problem is here, $data is empty when read has timed
> out, i.e, not
>                 # read a complete line. I expect data to contain the
> line read so
>                 # far.
>                 echo "$data" >&2
>
>                 [[ $ret -gt 128 ]] || continue
>
>                 # This is a futile attempt at getting the data I miss
> from the timed out
>                 # read above, this is just to prove that the data
> isn't there, even if I look
>                 # for these two other delimiters, I know that either
> one or the other will
>                 # be there.
>                 read -d ':' -t 1 data
>                 # Data is still empty here ...
>                 if [[ -n "$data" ]]
>                 then
>                         [[ "$data" =~ "login" ]] && return 0
>                 fi
>
>                 read -d '#' -t 1 data
>                 # ... and empty here too.
>                 if [[ -n "$data" ]]
>                 then
>                         [[ "$data" =~ 'root@' ]] && return 1
>                 fi
>
>                 # And data is empty on the next iteration of the loop too, 
> thus
>                 # read discarded the incomplete line of input, the
> line that holds
>                 # the login: prompt. And that line does not hold a
> newline so read
>                 # times out. And discards that data. =(
>
>         done < "$xl_console_output"
>
>
>
>
>> Pierre
>> PS: next time consider trimming your use case to avoid us avoid to search
>> for your problems.
>
> Sorry, just wanted to be thorough, hope this new trimmed example is better,
> and thanks for pointing out my mistake regarding while. =)
>
>     /  Linus

>From what I can see after a quick look, you are calling "read" inside
a "while read;do done < something" loop

The read inside will read inside the "do done" will read from the same
standard input as the one after "while" and it is connected to
"something" and not from the terminal.
Maybe you want something like:
while IFS= read -rd '' -u3 line;do ....

 read

done 3< <(find. .. -print0)

using another file descriptor (3) as input to the outer loop



reply via email to

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