On Nov 13, 2010, at 1:19 PM, Carlos A. M. dos Santos wrote:

> On Thu, Nov 11, 2010 at 6:12 PM, Devin Teske <dte...@vicor.com> wrote:
>> Hi fellow hackers... I come with baring gifts!
>> 
>> So, just as the subject-line says, ... here's an efficient and robust
>> spinner function compatible with many shells.
>>                        DONE=$( /bin/sh -c 'read -t 0 DONE; echo $DONE' )
> 
> Is this expected to be portable to other operating systems? The dash
> shell, used as /bin/bash in Ubuntu, does not acept the "-t" argument
> to the read builtin command. Using /bin/bash solves the problem.

I was shooting for bourne-shell, but later realized that bash's read statement 
functions fundamentally different than bourne's (hence the direct invocation of 
/bin/sh).

On FreeBSD:

$ echo 'Hello' | /bin/sh -c 'read -t 0 DONE; echo $DONE'
Hello
$ echo 'Hello' | /bin/bash -c 'read -t 0 DONE; echo $DONE'

$ echo 'Hello' | /bin/bash -c 'read -t 1 DONE; echo $DONE'
Hello
$ /bin/bash -c 'read -t 0.5 DONE; echo $DONE'
/bin/bash: line 0: read: 0.5: invalid timeout specification

As you can see from the above, passing a timeout specification of zero to 
bourne-shell has the desired effect... if the stdin file descriptor has 
something to offer the read-statement, input will be read up-to the ending 
newline. Whereas, you can see that bash's implementation returns nothing from 
the read despite data being available. Naturally, one can get the data into 
bash's read by using a timeout of one, but that would be unacceptable to our 
spinner to rotate the spinner one-quarter spin each second. Last, the potential 
work-around of using finer measurements of time is not allowed.

However, this shouldn't be considered a bug, given the following description of 
the timeout option in bash's InfoTex manual:

    `-t TIMEOUT'
          Cause `read' to time out and return failure if a complete
          line of input is not read within TIMEOUT seconds.  This
          option has no effect if `read' is not reading input from the
          terminal or a pipe.

Now, compare that with the description from bourne-shell's man-page (sh(1)):

             If the -t option is specified and the timeout elapses before any
             input is supplied, the read command will return without assigning
             any values.  The timeout value may optionally be followed by one
             of ``s'', ``m'' or ``h'' to explicitly specify seconds, minutes
             or hours.  If none is supplied, ``s'' is assumed.

So, as you can see, bash will timeout if a full line is not received in the 
duration specified as the timeout, while bourne-shell will timeout only if no 
input is supplied for the same duration.

For our purposes, we want bourne-shell's implementation, not bash's (at least 
on FreeBSD).

I also tested Mac OS X 10.6.1, FreeBSD-8.1, CentOS 4.7, RedHat Enterprise Linux 
(RHEL) 4 Nahant Update 4 (U4), and also RHEL4U8.

Here's the breakdown for the test of ``read -t 0 LINE; echo $LINE'':

Mac OS X 10.6.1:
        sh: FAIL
        bash: FAIL
RedHat Enterprise Linux (RHEL) 4 Update 4 (U4):
        sh: FAIL
        bash: FAIL
RedHat Enterprise Linux (RHEL) 4 Update 8 (U8):
        sh: FAIL
        bash: FAIL
CentOS 4.7:
        sh: FAIL
        bash: FAIL
FreeBSD-4.8:
        sh: SUCCEED
        bash: FAIL
FreeBSD-4.11:
        sh: SUCCEED
        bash: FAIL
FreeBSD-8.1:
        sh: SUCCEED
        bash: FAIL

This is not so surprising... On all of the above-tested Linux OSes, /bin/sh is 
a symbolic link to bash(1). On Mac OS X, /bin/sh is simply a bash binary (try 
/bin/sh --version).

It's rather unfortunate that bourne-shell has what we need but is not available 
on all operating systems since many OSes have started swapping out bourne-shell 
for it's younger cousin.

Does anyone else happen to know of a portable way to quickly check if data is 
available on a given file descriptor?
--
Cheers,
Devin Teske

-> CONTACT INFORMATION <-
Business Solutions Consultant II
FIS - fisglobal.com
510-735-5650 Mobile
510-621-2038 Office
510-621-2020 Office Fax
909-477-4578 Home/Fax
devin.te...@fisglobal.com

-> LEGAL DISCLAIMER <-
This message  contains confidential  and proprietary  information
of the sender,  and is intended only for the person(s) to whom it
is addressed. Any use, distribution, copying or disclosure by any
other person  is strictly prohibited.  If you have  received this
message in error,  please notify  the e-mail sender  immediately,
and delete the original message without making a copy.

-> END TRANSMISSION <-

_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to