What is the most portable syntax of these two choices?

5 views
Skip to first unread message

David Kirkby

unread,
Jul 27, 2010, 5:42:13 PM7/27/10
to
I have this in a script, where $UNAME will be the output of 'uname',
except on Cygwin, where it will be "CYGWIN".

What of the following two lines is more portable?

if [ "x$UNAME" != xSunOS ] && [ "x$UNAME" != xCYGWIN ] && [ "x$UNAME" !
= xHP-UX ]; then

or

if [ "$UNAME" = SunOS -a "$UNAME" = CYGWIN -a "$UNAME" = HP-UX ]; then

I believe the former is more portable, but someone has suggested the
use of the latter.

Dave

David Kirkby

unread,
Jul 27, 2010, 6:15:14 PM7/27/10
to

Sorry, that second line made no sense

if [ "$UNAME" = SunOS -o "$UNAME" = CYGWIN -o "$UNAME" = HP-UX ]; then

is what I was meaning.

Aragorn

unread,
Jul 27, 2010, 8:09:32 PM7/27/10
to
On Wednesday 28 July 2010 00:15 in comp.unix.shell, somebody identifying
as David Kirkby wrote...

> On Jul 27, 10:42 pm, David Kirkby <drkir...@gmail.com> wrote:
>> I have this in a script, where $UNAME will be the output of 'uname',
>> except on Cygwin, where it will be "CYGWIN".
>>
>> What of the following two lines is more portable?
>>
>> if [ "x$UNAME" != xSunOS ] && [ "x$UNAME" != xCYGWIN ] && [ "x$UNAME"
>> ! = xHP-UX ]; then
>>
>> or
>>
>> if [ "$UNAME" = SunOS -a "$UNAME" = CYGWIN -a "$UNAME" = HP-UX ];
>> then
>>
>> I believe the former is more portable, but someone has suggested the
>> use of the latter.
>

> Sorry, that second line made no sense
>
> if [ "$UNAME" = SunOS -o "$UNAME" = CYGWIN -o "$UNAME" = HP-UX ]; then
>
> is what I was meaning.

Well, both are Bourne-compatible expressions, but they are not
interchangeable.

In your first expression, whatever follows after "then" will only get
executed if the value of $UNAME matches none of the listed values,
while in the second command, what follows after "then" will get
executed if one of the tested conditions is true. So whatever follows
after "then" would have to be defined differently, depending on which
of the two commands you use. But I'm assuming that you know this and
that the portability or perhaps rather even the "recommendability" of
the method is your sole concern.

Technically, using...

if [ condition1 -o condition2 -o condition3 ]; then

... evaluates to true if either single condition is true, but also when
any combination of conditions evaluates to true.

In the example given, where it concerns the uname of any given
environment, there is of course little to no chance that you would get
a combination of different unames - no system will be *and* SunOS *and*
HP-UX at the same time - but the construct of the evaluation itself
does allow for that.

Your first line however...

if [ not_condition1 ] && [ not_condition2] && [ not_condition3 ]; then

... while being more elaborate in its evaluation, is more exclusive,
because all three of the conditions have to be met individually as
being "not true" before whatever follows after "then" is executed.

Therefore, personally, I would also opt for that first line if a strict
and exclusive evaluation is required for the success of the script. It
is, in my humble opinion, the more portable of the two, in that such a
construct can be more easily applied to multiple kinds of scripts,
while the second line (with the "-o") leaves more room for unforeseen
circumstances.

--
*Aragorn*
(registered GNU/Linux user #223157)

Thomas 'PointedEars' Lahn

unread,
Jul 28, 2010, 5:35:35 AM7/28/10
to
David Kirkby wrote:

> David Kirkby wrote:
>> I have this in a script, where $UNAME will be the output of 'uname',
>> except on Cygwin, where it will be "CYGWIN".
>>
>> What of the following two lines is more portable?
>>
>> if [ "x$UNAME" != xSunOS ] && [ "x$UNAME" != xCYGWIN ] && [ "x$UNAME" !
>> = xHP-UX ]; then
>>
>> or
>>
>> if [ "$UNAME" = SunOS -a "$UNAME" = CYGWIN -a "$UNAME" = HP-UX ]; then
>>
>> I believe the former is more portable, but someone has suggested the
>> use of the latter.
>

> Sorry, that second line made no sense
>
> if [ "$UNAME" = SunOS -o "$UNAME" = CYGWIN -o "$UNAME" = HP-UX ]; then
>
> is what I was meaning.

"$UNAME" might start with a `-', although I have found that to be explicitly
recommended against in BSD (passwd(5)); so the first variant is safer, both
with regard to prepending letter and using `&&' instead of `-a'/`-o'.

I do not think there is much of a difference in portability between the two
approaches. However, I think that `test' might be more portable than `[',
and that you should choose the boolean operator depending on what you think
is the more likely case; shortcut evaluation can increase overall
efficiency.


HTH
--
PointedEars

Sven Mascheck

unread,
Jul 28, 2010, 2:24:27 PM7/28/10
to
David Kirkby wrote:
> David Kirkby wrote:

>> What of the following two lines is more portable?
>>
>> if [ "x$UNAME" != xSunOS ] && [ "x$UNAME" != xCYGWIN ] && [ "x$UNAME" !
>> = xHP-UX ]; then
>>
>> or
>>
>> if [ "$UNAME" = SunOS -a "$UNAME" = CYGWIN -a "$UNAME" = HP-UX ]; then
>>
>

> Sorry, that second line made no sense
>
> if [ "$UNAME" = SunOS -o "$UNAME" = CYGWIN -o "$UNAME" = HP-UX ]; then


That's weird. Did you mean to ask

if [ "x$UNAME" != xSunOS ] && ....

or

if [ "x$UNAME" != xSunOS -a ...

but missed both the ! for negation and the extra-x in the second line
(let alone the update)? :-)

bsh

unread,
Aug 1, 2010, 5:35:18 PM8/1/10
to
David Kirkby <drkir...@gmail.com> wrote:
> I have this in a script, where $UNAME will be the output of 'uname',
> except on Cygwin, where it will be "CYGWIN".

P.S. I hope you are not writing your own host detection script.
The best one is config.guess from the autoconf distribution:

config.guess.sh; config.sub.sh: "determine 'canonical host triple'"
http://www.bothner.com/~bothner/software/config.guess

... But plenty others exist, including:

archguess.sh: "determine OS/distribution/version: NCA?"
http://sf.net/projects/archguess/

archit.sh: "guess machine's application architecture"
http://www.cs.indiana.edu/~kinzler/home/binp/archit

opsys.sh
http://www.cs.indiana.edu/~kinzler/home/binp/opsys

platform.sh: "platform identification utility"
<shtools-distribution>/platform.sh

whatami.sh: "determine type of host: contained-in Msys distribution"
http://www-unix.mcs.anl.gov/systems/software/msys/

> What of the following two lines is more portable?
> if [ "x$UNAME" != xSunOS ] && [ "x$UNAME" != xCYGWIN ] && [ "x$UNAME" !
> = xHP-UX ]; then
> or
> if [ "$UNAME" = SunOS -a "$UNAME" = CYGWIN -a "$UNAME" = HP-UX ]; then
> I believe the former is more portable, but someone has suggested the
> use of the latter.

Hello Dave,

I'm a bit confused as this is a question already asked and answered:

http://groups.google.com/group/comp.unix.shell/msg/257da9fb6fdaa19b

=Brian

Reply all
Reply to author
Forward
0 new messages