[net.unix-wizards] Semantics of test

jaap@mcvax.UUCP (Jaap Akkerhuis) (11/08/85)

In all the unix systems I know about there was the program test, to be used
inside shell programs.

test -w foo will return the exit status 0 when foo is writable.

However, if foo is a directory, and although I have permission to write in
the directory, it will have the exit status 1.
Odd as it seems at first hand, it can be interpret as correct. Even if you
own the directory, you cannot copy an arbitrary file "on top of it". (Your
file system would be seriously be corrupted). Let us call this the purist
view.

Another interpretation is that if you can create a file in the directory, the
directory can be considered writable. Let us call this the sloppy view.

Shells with a build in "test" command, like the sysV and the ksh take the
sloppy view.

These different interpretations of test -w give a problem in porting shell
programs.

Question: What to do. Change "test", so it will be sloppy or should the shells
	with build in "test" be reformed to take the purist view.


	Jaap Akkerhuis (mcvax!jaap)

PS. Of course, if I have a shell file which would take care of the
    interpretation differences, I would use /bin/test in all cases. But since
    AT&T in their infinite wishdom removed /bin/test, this is going to be
    a pain:
	if test -f /bin/test
	then
		TEST=/bin/test	#purist test found
	else
		TEST=test	#sloppy test found
	fi

    The rest is left as an exercise to the reader.

guy@sun.uucp (Guy Harris) (11/09/85)

> Odd as it seems at first hand, it can be interpret as correct. Even if you
> own the directory, you cannot copy an arbitrary file "on top of it". (Your
> file system would be seriously be corrupted). Let us call this the purist
> view.

Let's not, and say we did.  Sun's "/bin/test" uses "access", rather than
"open", to test writability, so it will say that a directory is writable iff
you have the appropriate write permission bit set.  If "-w" tries to open
for writing, as it does in V7 and 4.xBSD, it is impossible to use "test" to
see if you could create a file in a directory, move a file to that
directory, or remove a file from that directory.  If, however, it is just a
shell-level front end for "access" (which is *my* definition of a "purist"
view"), you can do that very test.  If you want to test whether you can open
something for writing, try using the shell's front end for opening for
writing, namely ">>".  Try

	if [ -f "$file" ] && (>> "$file") 2>/dev/null
	then
		echo writable
	else
		echo not writable
	fi

The "2>/dev/null" is to suppress complaints if it can't open it for
writing; ">>" is used instead of ">" for obvious reasons.  This works fine
in S3/S5 systems, where "-f" returns "true" if it exists *and* it isn't a
directory; it's not perfect in V7/4.x systems, where it returns true if it
exists and it *is* a plain file (you can try throwing in tests for character
special and block special in these cases, which tests will never be
performed on an S3/S5 system because if it's character or block special the
"-f" test succeeds).

> Another interpretation is that if you can create a file in the directory,
> the directory can be considered writable. Let us call this the sloppy view.

Again, let's not.  This interpretation can be useful, as mentioned above;
it's hardly "sloppy", considering either kind of test is a straightforward
interface to a particular system call ("open(<filename>, <mode>)" or
"access(<filename>, <mode>)").

> These different interpretations of test -w give a problem in porting shell
> programs.
> 
> Question: What to do. Change "test", so it will be sloppy or should the
> shells with build in "test" be reformed to take the purist view.

Change "test" so it will be *useful*, not "sloppy"; shells with built-in
"test" can already test whether something can be opened.  Changing the shel
isn't a "reform", since it renders it inconvenient to test whether something
is a writable directory (you can do it, but you have to write your own
program).

	Guy Harris