[comp.bugs.4bsd] Bug/Feature in `test'

wagner@iaoobelix.UUCP (04/02/87)

[ Hey, lineeater! This line is for you! ]

The following might be a bug, it might be a feature. Anyway, it is one of the
little trivial problems one faces when porting shell scripts from a Sun OS3.2
to a VAX BSD4.2/uVAX ULTRIX.

The file `try' contains the following:

	#! /bin/sh
	if [ "$1" = "-d" ] 
	then
	    echo ok
	fi

The I typed in:

	% try 8
	bad
	% try -d

What did I get??? Guess!

On the Sun (OS 3.2):	try -d => ok
On the VAX (BSD 4.2):	try -d => bad
On the uVAX (ULTRIX):	try -d => bad

At least one of the three machines above did something wrong! My question to
net.land is "which one?"

It is just annoying to use workarounds like putting a dummy char in front of
each string or writing cases, etc...

Thanx 1e6 in advance,
Juergen Wagner,		      USENET: ...seismo!unido!iaoobel!wagner
("Gandalf")			or	  ...!pyramid!iaoobel!wagner

Mail:	Juergen Wagner
	Fraunhofer-Institut IAO
	Rosenbergstr. 28
	D-7000 Stuttgart 1
	Federal Republic of Germany
Phone:	+ 49 711 6648-205

wagner@iaoobelix.UUCP (04/02/87)

/***** iaoobelix:comp.bugs.4bsd / wagner / 10:37 am  Apr  2, 1987*/

That's what happens if there are several files with similar names.
If you wondered where the `bad' came from... here is the actual sh script:

	#! /bin/sh
	if [ "$1" = "-d" ] 
	then
	    echo ok
	else
	    echo bad
	fi

Juergen Wagner,		      USENET: ...seismo!unido!iaoobel!wagner

dce@mips.UUCP (04/03/87)

In article <6200001@iaoobelix.UUCP> wagner@iaoobelix.UUCP writes:
>The file `try' contains the following:
>
>	#! /bin/sh
>	if [ "$1" = "-d" ] 
>	then
>	    echo ok
>	fi
>
>The I typed in:
>
>	% try 8
>	bad
>	% try -d

This answer may not be the one you are fishing for, but I think it is
useful nonetheless.

When you say "try -d", the test line gets interpreted as

	[ "-d" = "-d" ]

which is syntactically incorrect given the definition of test, which says
that a -d is followed by a name which is checked to see if it is a
directory. It doesn't specifically say that '=' takes precedence over '-d',
so you can never assume that it does (or that '-d' takes precedence).

You have to be completely clear (I want to say unambiguous, but won't).

My own habit is to always say

	[ " value" op " value" ]

This has three advantages:

	1. It is syntactically clear.
	2. It forces you to put quotes around the values, which avoids
	   problems with variables containing spaces/tabs, and makes the
	   values stand out.
	3. It is aesthetically pleasing (as opposed to the more common

		[ xvalue op xvalue ]

	   which breaks when spaces/tabs are used)

As an alternative, 'case' works quite well for string comparisons, and
for number equality if you know what the numbers look like (i.e., you
can check for $# being equal to a specific value, since $# will be
expanded with no extra spaces or tabs or leading 0s).
-- 
David Elliott		{decvax,ucbvax,ihnp4}!decwrl!mips!dce

amos@instable.UUCP (04/05/87)

In article <256@quacky.mips.UUCP> dce@quacky.UUCP (David Elliott) writes:
>In article <6200001@iaoobelix.UUCP> wagner@iaoobelix.UUCP writes:
>>The file `try' contains the following:
>>
>>	#! /bin/sh
>>	if [ "$1" = "-d" ] 
>>	then
>>	    echo ok
>>	fi

Problems with 'test' aside, you can avoid using it altogether by doing:

case "$1" in
-d) echo ok ;;
*)  echo bad ;;
esac

'case' is builtin while test (a.k.a. '[') usually isn't, and it also
interprets flags in its own way. The 'case' syntax is a little more
complicated, but if string comparison is all you need,
'case' is the way to go.
-- 
	Amos Shapir
National Semiconductor (Israel)
6 Maskit st. P.O.B. 3007, Herzlia 46104, Israel  Tel. (972)52-522261
amos%nsta@nsc.com {hplabs,pyramid,sun,decwrl} 34.48'E 32.10'N