[net.unix-wizards] In sh, is '[' a portable synonym for 'test'?

roy@phri.UUCP (Roy Smith) (09/30/85)

	On my 4.2bsd system, the following do the same thing in sh because
/bin/[ is a link to /bin/test.  Test checks to see if it was called as "["
and in that case looks for the matching "]" at the end of the command.

	if test -r wombat; then echo I can read wombat; fi
	if [ -r wombat ]; then echo I can read wombat; fi

	This is not documented anywhere in the 4.2 manual (that I can find)
but seems to be common practice.  Is the "[]" form safe to use if you want
to make something portable?  My Sys5 manual (January 1983) notes the two
forms but mentions that the second is not recognized on all systems.  Does
anybody know on what systems it will fail?
-- 
Roy Smith <allegra!phri!roy>
System Administrator, Public Health Research Institute
455 First Avenue, New York, NY 10016

guy@sun.uucp (Guy Harris) (10/13/85)

> 
> 	On my 4.2bsd system, the following do the same thing in sh because
> /bin/[ is a link to /bin/test. ... Is the "[]" form safe to use if you want
> to make something portable?  My Sys5 manual (January 1983) notes the two
> forms but mentions that the second is not recognized on all systems.  Does
> anybody know on what systems it will fail?

V7 systems where /bin/[ isn't a link to /bin/test.  Any V7 or post-V7 system
can be made to support "if [ <condition> ]" as equivalent to "if test
<condition>", but the S5 manual properly warns you that not all systems have
been made to support it.  If you want to make something portable, and you
don't think you can convince every recipient of the program to make that
link, you're best off not using "[ ... ]".

	GUy Harris

john@moncol.UUCP (John Ruschmeyer) (10/15/85)

>From: guy@sun.uucp (Guy Harris)
>Message-ID: <2887@sun.uucp>
>Organization: Sun Microsystems, Inc.
>
>V7 systems where /bin/[ isn't a link to /bin/test.  Any V7 or post-V7 system
>can be made to support "if [ <condition> ]" as equivalent to "if test
><condition>", but the S5 manual properly warns you that not all systems have
>been made to support it.  If you want to make something portable, and you
>don't think you can convince every recipient of the program to make that
>link, you're best off not using "[ ... ]".

Any good reason *NOT* to make the link?


-- 
Name:		John Ruschmeyer
US Mail:	Monmouth College, W. Long Branch, NJ 07764
Phone:		(201) 222-6600 x366
UUCP:		...!vax135!petsd!moncol!john	...!princeton!moncol!john
						   ...!pesnta!moncol!john

	    "It all started out as a mild curiousity in a junkyard...
	    and now it's turned out to be quite a spirit of adventure."

carl@bdaemon.UUCP (carl) (10/15/85)

> > 
> > 	On my 4.2bsd system, the following do the same thing in sh because
> > /bin/[ is a link to /bin/test. ... Is the "[]" form safe to use if you want
> > ....
> 
> V7 systems where /bin/[ isn't a link to /bin/test.  Any V7 or post-V7 system
> can be made to support "if [ <condition> ]" as equivalent to "if test
> .....
> 	GUy Harris

I have absolutely no arguments with Guy's message, but would like to point
out that the [ condition ] construct saves only one keystroke at the
expense of readability.  E.g.:

	if test -f "$1"	<= 15 keystrokes + <CR>
vs.
	if [ -f "$1" ]	<= 14 keystrokes + <CR>

Which is more readable? Note that the spaces around [] are MANDATORY.

Carl Brandauer

ado@elsie.UUCP (Arthur David Olson) (10/17/85)

> Any good reason *NOT* to make the link?

If you want your software to be portable to sites where the administrators
refuse to make the link (for *whatever* reason), don't make the link on your
own site.
--
UNIX is an AT&T Bell Laboratories trademark.
Sun is a Sun Microsystems trademark.
Sh is an American Librarians Association trademark.
--
	UUCP: ..decvax!seismo!elsie!ado    ARPA: elsie!ado@seismo.ARPA
	DEC, VAX and Elsie are Digital Equipment and Borden trademarks

guy@sun.uucp (Guy Harris) (10/18/85)

> 	if test -f "$1"	<= 15 keystrokes + <CR>
> vs.
> 	if [ -f "$1" ]	<= 14 keystrokes + <CR>
> 
> Which is more readable?

The latter, obviously; it reads more like a conditional statement rather
than a command.  It may be *implemented* as a command (which, if the command
isn't builtin, slows it down - somebody who complained that "test" shouldn't
be built in was later seen using a "case" statement instead of an "if" and a
"test" in order to make it run faster), but that fact isn't relevant to
understanding what it *does*.

Good grief, do you think that people use the square bracket to save one
measly keystroke?  That's not why it's there - it's there to improve the
readability of the statement.

	Guy Harris

john@moncol.UUCP (John Ruschmeyer) (10/20/85)

>From: ado@elsie.UUCP (Arthur David Olson)
>Message-ID: <5242@elsie.UUCP>
>Organization: NIH-LEC, Bethesda, MD
>
>> Any good reason *NOT* to make the link?
>
>If you want your software to be portable to sites where the administrators
>refuse to make the link (for *whatever* reason), don't make the link on your
>own site.

Actually, that almost sounds like a good reason to make the link, but
never use it in your own software. Therefore you do have some compatability
with the Sys V and 4.2 programmers who use '[' instead of 'test'.

Now if there was a patch for the v7 'sh' to use '#' as a real comment....

-- 
Name:		John Ruschmeyer
US Mail:	Monmouth College, W. Long Branch, NJ 07764
Phone:		(201) 222-6600 x366
UUCP:		...!vax135!petsd!moncol!john	...!princeton!moncol!john
						   ...!pesnta!moncol!john

	    "It all started out as a mild curiousity in a junkyard...
	    and now it's turned out to be quite a spirit of adventure."

guy@sun.uucp (Guy Harris) (10/22/85)

> Now if there was a patch for the v7 'sh' to use '#' as a real comment....

If you don't have an S5 license, get the 4.xBSD 'sh' (assuming you have a
32V license); it's the V7 shell with '#' as a real comment (but it treats
any file whose first character is '#' as a C shell script).  If you *do*
have an S5 license, use its shell instead - it's much improved (the S5R2
version even has Bourne's bastard Algol 68 expunged, finally, although it
still has the whacky method for storage allocation which causes plenty of
problems on machines which won't let user-mode code restart or continue
instructions).

	Guy Harris

latham@bsdpkh.UUCP (Ken Latham) (10/23/85)

In reference to what I assume was the original question....

	In sh, is ' [ ... ] ' a portable synonym for 'test ... '


The answer ( according to Bell Laboratories ) is NO!

See Unix system V Programmer's manual ( under 'test' )
( it states that SOME unix systems accept this notation )

However, both system V and system V.2 accept it! ( I double checked! )

	I personally do not use it as it tends to mislead some people
into believing that it is an internal function of the shell.

					Yours, ( well may not *yours* )

						Ken Latham

		( signature is in the primordial stages )

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (10/24/85)

> ...  If you *do*
> have an S5 license, use its shell instead - it's much improved (the S5R2
> version even has Bourne's bastard Algol 68 expunged, finally, although it
> still has the whacky method for storage allocation which causes plenty of
> problems on machines which won't let user-mode code restart or continue
> instructions).

This is real easy to fix.

/*	@(#)blok.c	1.4	*/
...
addblok(reqd)
...
	bloktop = bloktop->word = (struct blk *)(Rcheat(bloktop) + reqd);
#ifdef mc68000	/* or if you just want to be sure */
	/* at this point, bloktop may be beyond the break.  I haven't been
	 * able to make the 68010 allow you to continue from a user bus
	 * trap after executing a signal handler that fixes up the bus
	 * trap, so we'll simply do a more intelligent thing and test
	 * the bloody thing before we use it.  -- Wes Chalfant, FileNet Corp.
	 */
	if ((char *)&bloktop->word >= brkend)
		fault(SIGSEGV);
#endif
	bloktop->word = (struct blk *)(brkbegin + 1);

carl@bdaemon.UUCP (carl) (10/24/85)

> > 	if test -f "$1"	<= 15 keystrokes + <CR>
> > vs.
> > 	if [ -f "$1" ]	<= 14 keystrokes + <CR>
> > 
> > Which is more readable?
> 
> The latter, obviously; it reads more like a conditional statement rather
> than a command.

Hogwash.  The manual states

	if *list* then *list* [ elif *list* then *list* ] ...

where *list* is defined  as a sequence on one or more pipelines ,i.e
commands. *Test* is a command like any other, so why should it be treated
any differently?

> It may be *implemented* as a command (which, if the command
> isn't builtin, slows it down - somebody who complained that "test" shouldn't
> be built in was later seen using a "case" statement instead of an "if" and a
> "test" in order to make it run faster), but that fact isn't relevant to
> understanding what it *does*.

Agreed, irrelevant to the present discussion.

> Good grief, do you think that people use the square bracket to save one
> measly keystroke?  That's not why it's there - it's there to improve the
> readability of the statement.
> 
> 	Guy Harris

Yes, but only by people who want to obscure the fact that "if tests the
value returned by the last simple command following it" (S. R. Bourne,
The UNIX System, page 58).

Carl Brandauer

mike@whuxl.UUCP (BALDWIN) (10/26/85)

> > > 	if test -f "$1"	<= 15 keystrokes + <CR>
> > > vs.
> > > 	if [ -f "$1" ]	<= 14 keystrokes + <CR>
> > > 
> > > Which is more readable?
> > 
> > The latter, obviously; it reads more like a conditional statement rather
> > than a command.
> 
> Hogwash.  The manual states
> 
> 	if *list* then *list* [ elif *list* then *list* ] ...
> 
> where *list* is defined  as a sequence on one or more pipelines ,i.e
> commands. *Test* is a command like any other, so why should it be treated
> any differently?

Who cares WHAT [ or test really are?  I *like* if statements to look like if
statement, thank you.
	if [ $x = 3 ]
is more pleasing AND READABLE to me than
	if test $x = 3

> > Good grief, do you think that people use the square bracket to save one
> > measly keystroke?  That's not why it's there - it's there to improve the
> > readability of the statement.
> > 
> > 	Guy Harris
> 
> Yes, but only by people who want to obscure the fact that "if tests the
> value returned by the last simple command following it" (S. R. Bourne,
> The UNIX System, page 58).

Oh, bushwah!  I don't want to obscure what the if stmt does, I want to
make it LESS obscure.  If you ask me, "if test expr" is obscuring the
fact that this is a simple conditional, whereas "if [ expr ]" is obvious.

Speaking of test, is anyone else out there annoyed that there really
isn't a good way to deal with strings?  Instead of nice and simple
[ "$x" = foo ] you have to say [ "X$x" = Xfoo ] which is kinda ugly.
Also, [ -n "$x" ] is right out (what if x is "="?), along with -z.
Expr has the same problem with "expr string : regexp".  Bleah!
-- 
						Michael Baldwin
						{at&t}!whuxl!mike

jqj@cornell.UUCP (J Q Johnson) (10/26/85)

Although I personally prefer to write using [] rather than test, it has
the disadvantage of obscuring the generality of sh.  After all, the
conditional can be an arbitrary list, so
	if [ x = y ]; true; then echo yes; fi
prints "yes".  More generally, thinking of  [] as part of a special-purpose
conditional construct obscures the need for the following ";".  I have
several times made the syntax error:
	if [ -r whatever ] then
If I'd been using test, I wouldn't have forgotten the ";", since the
conditional would obviously have needed termination.

oer@isosvax.UUCP (Ed Reeder) (11/04/85)

Another reason '[' is used instead of test is it prevents problems
when the user has a file named 'test' in his current directory AND
his search path searches his current directory before /bin (for
systems that don't have test built in to the shell).

While everyone should reset PATH to avoid the problem, we don't
(as evidenced by net.sources).

Ed Reeder
Intel Corporation
Phoenix