[net.unix] Why do people use: if [ "x$FOO" = "x" ] .... ?

wcs@ho95b.UUCP (Bill Stewart) (04/09/85)

	I've seen a lot of Bourne shell scripts that test for
blank variables using the construct
	if [ "x$FOO" = "x" ]

Why the x's?  If you leave out the quotes, then the test dies if $FOO
is empty, but why not just use
	if [ "$FOO" = "" ]
or
	if [ -z "$FOO" ]

I've seen this construct in new code as well as old, from reputable
programmers.  I've checked a few obscure cases like
	FOO='`echo You Lose!!`'
but even they don't die.  Is this just another superstition, like
	sync; sync; sync;
or am I forgetting something stupid and obvious?
			Thanks;
				Bill Stewart, AT&T Bell Labs, Holmdel NJ
				{ihnp4,allegra,cbosg}!ho95c!wcs

rpw3@redwood.UUCP (Rob Warnock) (04/17/85)

There is one case... uh, situation... in which the x$FOO construct (NO quotes!)
is useful, and that's when you are trying to allow partial matching. (But see
the caveat that follows.)

Suppose you are asking for confirmation and you want any of "y", "ye",
or "yes", or "yo" or anything else starting with "y" to mean "yes",
and anything starting with "n" to mean "no". (Yes, this is not good
human engineering, but gimme a break, for the example's sake!). Then
you would use:

	echo -n 'Do it? '	# echo 'Do it? \c' for System V
	read answer
	case X$answer in
	Xy*)	... yes ... ;;
	Xn*)	... no ... ;;
	*)	echo 'Please type yes or no"... ;;
	esac

Using "$answer" doesn't work unless you explicitly list ALL of the choices,
since "*" isn't expanded inside strings, so you have to do this:

	case "$answer" in
	"y"|"ye"|"yes"|"yep"|"yea"|"yeah"|"yo")	... yes ...;;
	"n"|"no"|"nope"|"nada"|"nah")		... no ...;;
	*)					echo 'I do not understand...' ;;
	esac

Be that as it may, I have started using the latter form myself, as the
X$answer form does not protect against (even accidental) typing of multiple
words in the answer. The "$answer" form does not blow up in this case,
and so is preferred (by fumble-fingers such as myself). I generally allow
only "y" and "yes" for YES and "n" and "no" for NO; I have found I get few
complaints from "nay"-sayers... ;-}


Rob Warnock
Systems Architecture Consultant

UUCP:	{ihnp4,ucbvax!dual}!fortune!redwood!rpw3
DDD:	(415)572-2607
USPS:	510 Trinidad Lane, Foster City, CA  94404

wcs@homxb.UUCP (Bill Stewart HO 4K-437 x0705) (04/19/85)

Last week I posted an article asking why people use constructs
like the above instead of if [ -z "$FOO" ] or if [ "Known" = "$FOO" ]
Yeah, I should have worried about the case where $FOO has a value
special to test, such as "-z" or "=".  The most interesting reply
pointed out that the answers were different on 4.2BSD.

For both ksh and SysV /bin/sh, the = operator has higher precedence
than -z or -n.  For 4.2 BSD it doesn't.
	if [ -z = -z ] ; then echo true ; else echo false ; fi
On SysV and ksh, this prints "true"; on 4.2BSD it prints "false".
On the other hand,
	if [ -z = ] ; then echo true ; else echo false; fi
On 4.2BSD this prints "false"; on ksh and SysV it prints
	"sh: test: argument expected"

So, those leftover-from-v6 constructs with the "x$FOO" are
still useful.
		Bill Stewart, ho95c!wcs
-- 
"The {first,last} major program written in ADA will be a COBOL interpreter."
					Stewart, 1984
Bill Stewart
AT&T Bell Labs, Holmdel NJ
HO 4K-435 x0705   (201-949-0705)
ho95b!wcs
ucbvax!ihnp4!ho95b!wcs
decvax1harpo!ho95b!wcs

lmcl@ukc.UUCP (L.M.McLoughlin) (04/19/85)

In article <361@ho95b.UUCP> wcs@ho95b.UUCP writes:
>
>	I've seen a lot of Bourne shell scripts that test for
>blank variables using the construct
>	if [ "x$FOO" = "x" ]
>
...
>	if [ "$FOO" = "" ]
>or
>	if [ -z "$FOO" ]

How about:
	case "$FOO"
	in
	'') echo ALL GONE;;
	*) echo Something here;;
	esac

Unless you have '[' built into your shell this is generally a lot faster
but maybe less readable.

I too used to use the "x$VAR" type tests and kicked myself when I saw the
case equivalent in the rn sources.

henry@utzoo.UUCP (Henry Spencer) (04/21/85)

> Suppose you are asking for confirmation and you want any of "y", "ye",
> or "yes", or "yo" or anything else starting with "y" to mean "yes",
> and anything starting with "n" to mean "no". ...
> 
> Using "$answer" doesn't work unless you explicitly list ALL of the choices,
> since "*" isn't expanded inside strings...

Huh?  The following has always worked perfectly for us, on both V7
and SysV shells:

	case "$answer"
	in
		y*)
		echo yes
		;;

		n*)
		echo no
		;;

		*)
		echo huh
		;;
	esac

Just to be doubly sure, I just wrote out the above example and tried
it.  Works fine.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry