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 <[email protected]> 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
[email protected]
-> 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 <-
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[email protected]"