> -----Ursprüngliche Nachricht----- > Von: Chet Ramey [mailto:chet.ra...@case.edu] > Gesendet: Samstag, 15. Dezember 2012 23:53 > > On 12/14/12 6:28 AM, Fiedler Roman wrote: > > Hello list, > > > > One of our bash-scrips failed with very low frequency but randomly. The > result was that exactly 1 byte was lost, so the string returned by "read -t 1" > was too short. The culprit seems to be the built-in read function itself, the > probability of failure was about 1:100000 in our case. > > > > After analysis and creation of a reliable reproducer, I'm not sure if this > > is a > programming error in bash or a bug in our script as the result of suboptimal > documentation. > > > > * Description: > > > > When "read" builtin is used with timeout setting, both with "-t" option or > > by > setting the "TMOUT" environment variable, and the timeout occurs when > some bytes of line were already received by bash, then those bytes are > silently dropped. The next "read" returns the remainder of the line. > > You don't say what version of bash you're using, ...
Sorry, forgot to mention it: # bash --version GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> > but the following change went in with bash-4.0: > > k. Changed the behavior of the read builtin to save any partial input > received > in the specified variable when the read builtin times out. This also > results in variables specified as arguments to read to be set to the empty > string when there is no input available. When the read builtin times out, > it returns an exit status greater than 128. That is strange: If I understand correctly, following script combined with the one from first mail should still fail, but with different error. But it fails in a way similar to discarding partial input, not saving it. Could it be, that Ubuntu-bash works differently? Output on my side is: Script: #!/bin/bash line="" while true; do read -t 1 line status="$?" if [ "${status}" != "0" ]; then echo "Read status ${status}, value \"${line}\"" >&2 continue fi if [ "${line}" != "Status: OK" ]; then echo "FAILED READ: \"${line}\"" >&2 exit 1 fi done # ./FragmentedSend.py | ./BashReadTest Read status 142, value "" Read status 142, value "" FAILED READ: "us: OK" Traceback (most recent call last): File "./FragmentedSend.py", line 16, in <module> os.write(1, nextSendData[0:sendLength]) OSError: [Errno 32] Broken pipe >From your description, I would expect --- HYPOTHETICAL-OUTPUT--- # ./FragmentedSend.py | ./BashReadTest Read status 142, value "" Read status 142, value "Stat" << the partial read FAILED READ: "us: OK" Traceback (most recent call last): File "./FragmentedSend.py", line 16, in <module> os.write(1, nextSendData[0:sendLength]) OSError: [Errno 32] Broken pipe --- HYPOTHETICAL-OUTPUT--- Is this consistent with what you would be expecting! > That is not clearly stated in the manual's description of `read'. Perhaps it could be added, at least "see specification [URL] for details on read input handling" Roman