[comp.bugs.sys5] compressdir bug?

root@hawkmoon.MN.ORG (Admin) (08/30/88)

I don't know why i haven't ever seen anyone complain about this little bug (?),
but i suspect that it is because no one ever uses the auxilliary utility called
compressdir that came with the compress 4.0 distribution.

The problem is that compressdir, upon invokation, never finds any files to
compress.  Here is the patch to correct the problem:

There is a missing `!' just before the -exec in the find.

Maybe only my copy of compressdir was corrupted -- either that or i simply
don't know how to use the program...  But it seems to work for me now.
Hope this helps someone out there.

---------------------cut me here-----------------------------------------------
*** compressdir.org	Mon Aug 29 12:57:58 1988
--- compressdir.new	Fri Aug 26 19:47:42 1988
***************
*** 11,16 ****
  	FILES="."
  fi
  set $FILES
! find $@ -type f -links 1 -exec test -r {} -a -s {} \; \
  -exec expr '(' {} : '.*\.Z' ')' '=' 0 \; \
  -exec compress $OPTIONS {} \; #>/dev/null
--- 11,16 ----
  	FILES="."
  fi
  set $FILES
! find $@ -type f -links 1 ! -exec test -r {} -a -s {} \; \
  -exec expr '(' {} : '.*\.Z' ')' '=' 0 \; \
  -exec compress $OPTIONS {} \; #>/dev/null
-- 
Derek Terveer		root@hawkmoon.MN.ORG
			w(612)681-6986	h(612)688-0667

"A proper king is crowned" -- Thomas B. Costain

stu@gtisqr.UUCP (Stu Donaldson) (09/02/88)

In article <303@hawkmoon.MN.ORG>, root@hawkmoon.MN.ORG (Admin) writes:

> There is a missing `!' just before the -exec in the find.

		find $@ -type f -links 1 -exec test -r {} -a -s {} \; \
		-exec expr '(' {} : '.*\.Z' ')' '=' 0 \; \
		-exec compress $OPTIONS {} \; >/dev/null

	My copy of compressdir does not have the '!' and works
	just as I expect it to.  The test after the first exec
	is testing to see if the file is readable, and has a
	size greater than 0.  If you put a '!' in, then things
	shouldn't work, because it will only try and compress
	files that either aren't readable, or have a size of 0.

	Did I misunderstand something?

> Derek Terveer		root@hawkmoon.MN.ORG
> 			w(612)681-6986	h(612)688-0667
>
> "A proper king is crowned" -- Thomas B. Costain


-- 
Stu Donaldson          UUCP: uw-beaver!uw-nsr!uw-warp!gtisqr!stu
Global Tech Int'l Inc. ARPA: uw-nsr!uw-warp!gtisqr!stu@beaver.cs.washington.edu
Mukilteo WA, 98275     Bell: (206) 742-9111
 PS, use one of the above return addresses, the From field is probably hosed.

det@hawkmoon.MN.ORG (Derek E. Terveer) (09/05/88)

In article <442@gt-ford.gtisqr.UUCP>, stu@gtisqr.UUCP (Stu Donaldson) writes:
> In article <303@hawkmoon.MN.ORG>, root@hawkmoon.MN.ORG (Admin) writes:
> 
> > There is a missing `!' just before the -exec in the find.
> 
> 		find $@ -type f -links 1 -exec test -r {} -a -s {} \; \
> 		-exec expr '(' {} : '.*\.Z' ')' '=' 0 \; \
> 		-exec compress $OPTIONS {} \; >/dev/null
> 
> 	My copy of compressdir does not have the '!' and works
> 	just as I expect it to.  The test after the first exec
> 	is testing to see if the file is readable, and has a
> 	size greater than 0.  If you put a '!' in, then things
> 	shouldn't work, because it will only try and compress
> 	files that either aren't readable, or have a size of 0.
> 
> 	Did I misunderstand something?

I don't think so -- your analysis of the command is correct, however perhaps
this is a case where i may be forced to stick my foot in my mouth and wiggle my
toes vigoursly... (:-(  I assumed that because it didn't seem to work on MY
system (uPort V/386 3.0-L2.2) that it was a bug.

I any event this is why i decided to insert the "!" (before the first exec) in
my copy of compressdir:

$ cd /tmp
$ touch f		#create a file
$ chmod 777 f		#make it readable
$ ls -l /tmp/f		#show it as readable, n'est pas?
-rwxrwxrwx   1 det      sys           39 Sep  2 01:05 /tmp/f
$ type test		#where am i picking up test?
test is a shell builtin
$ ls -l /bin/test /usr/bin/test /usr/ubin/test	#check for test commands
/bin/test: No such file or directory
/usr/bin/test: No such file or directory
/usr/ubin/test: No such file or directory
$ test -r /tmp/f;echo $?	#test test  -- seems to work as expected..
0
$ find f -type f -links 1 -exec test -r {} \; -print	#should print "f" - no!
$ find f -type f -links 1 ! -exec test -r {} \; -print	#try the reverse - yes
f
$ echo exit 0 >/tmp/retcode	#create a program to return an exit code
$ chmod 777 /tmp/retcode	#make it executable
$ find f -type f -links 1 -exec /tmp/retcode \; -print	#this works as expected
f
$ echo exit 1 >/tmp/retcode	#reverse sense of exit code
$ find f -type f -links 1 -exec /tmp/retcode \; -print	#so does this!
$ 

So what is going on here?  Now, did I misunderstand something????

Is find using some other "test" than the one that is accessable from the shell?
(ksh, by the way)

derek
-- 
Derek Terveer		det@hawkmoon.MN.ORG
			w(612)681-6986	h(612)688-0667

"A proper king is crowned" -- Thomas B. Costain

ditto@cbmvax.UUCP (Michael "Ford" Ditto) (09/09/88)

In article <318@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
>$ test -r /tmp/f;echo $?	#test test  -- seems to work as expected..
>0
>$ find f -type f -links 1 -exec test -r {} \; -print	#should print "f" - no!
 [ It doesn't print "f" ]
 [ ... ]

>So what is going on here?  Now, did I misunderstand something????

Well, you sort-of answer your own question just before:

>$ ls -l /bin/test /usr/bin/test /usr/ubin/test	#check for test commands
>/bin/test: No such file or directory
>/usr/bin/test: No such file or directory
>/usr/ubin/test: No such file or directory

The problem is that you do not HAVE the "test" program on your system.
The bug here is that the find program doesn't complain when it can't
exec the argument to "-exec".  It does, at least, return a nonzero
status from the attempt; that's why your added "!" made it always
return success.

>Is find using some other "test" than the one that is accessable from the shell?
>(ksh, by the way)

Well, the "test" command you tested is *built in* to the shell, and
therefore not accessable from anywhere else.  (Find can only exec
"real" programs, not shell built-in commands.)  You could modify
your command to run a shell:

$ find f -type f -links 1 -exec sh -c "test -r $0" {} \; -print

although that example relies on an undocumented feature of the
Bourne shell (That $0 is the first agrument when the -c option is
used).

The best solution would be to get a copy of the "test" program.
You might already have it under the name "/bin/[", in which case
you can just make a link.
-- 
					-=] Ford [=-

	.		.		(In Real Life: Mike Ditto)
.	    :	       ,		ford@kenobi.cts.com
This space under construction,		...!ucsd!elgar!ford
pardon our dust.			ditto@cbmvax.commodore.com

stu@gtisqr.UUCP (Stu Donaldson) (09/14/88)

In article <318@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
>In article <442@gt-ford.gtisqr.UUCP>, stu@gtisqr.UUCP (Stu Donaldson) writes:
>> In article <303@hawkmoon.MN.ORG>, root@hawkmoon.MN.ORG (Admin) writes:
>>
>> > There is a missing `!' just before the -exec in the find.
>
>I don't think so -- your analysis of the command is correct, however perhaps
>this is a case where i may be forced to stick my foot in my mouth and wiggle my
>toes vigoursly... (:-(  I assumed that because it didn't seem to work on MY
>system (uPort V/386 3.0-L2.2) that it was a bug.
>
>I any event this is why i decided to insert the "!" (before the first exec) in
>my copy of compressdir:

>$ ls -l /bin/test
>/bin/test: No such file or directory

Some time after I posted my response, I found that compressdir didn't
work on another of our machines.  Upon investigation, I found that /bin/test
was missing.  Then I recalled, that it was missing missing from the uPort
System V/386 distribution, and I had created my own '/bin/test' to fix
this sort of problem.

I don't know if /bin/test is supposed to be there, and isn't, or if they
just left it off of the V/386 release.

The simple case of the problem is this:

	find . -exec test -r {} \; -print

This will cause find to execute the command 'test -r FILENAME'
for each file it finds.  This will fail, because there is no
command 'test'.  'test' is internal to the shell, and was apparently
not placed in /bin/test.

Placing a '!' in front of the exec part of the 'find' command seems
to me to be definately the wrong way to solve the problem.  You are
relying on the exec command of 'test ...' to fail.

As I said, my solution was to create /bin/test.  Here is a copy,
it is incredibly simple.

	:
	# /bin/test
	if [ $* ]
	then
	  exit 0
	else
	  exit 1
	fi

As you can see, it relies on the test command implimented within
the shell.  I wonder if anyone has brought this up with microport?

>derek
>--
>Derek Terveer		det@hawkmoon.MN.ORG
>			w(612)681-6986	h(612)688-0667
>
>"A proper king is crowned" -- Thomas B. Costain
-- 
Stu Donaldson          UUCP: uw-beaver!uw-nsr!uw-warp!gtisqr!stu
Global Tech Int'l Inc. ARPA: uw-nsr!uw-warp!gtisqr!stu@beaver.cs.washington.edu
Mukilteo WA, 98275     Bell: (206) 742-9111
 PS, use one of the above return addresses, the From field is probably hosed.

david@ms.uky.edu (David Herron -- One of the vertebrae) (09/15/88)

/bin/test should definitely be there.  '[' should be a link to /bin/test.
It's only a few K of disk space so I don't see any strong reason why
they should leave it out ... um, never mind.  /bin/test doesn't exist
on my Unix PC and I never noticed it missing until now.  '[' isn't there
either ...
-- 
<---- David Herron -- One of the MMDF guys                   <david@ms.uky.edu>
<---- ska: David le casse\*'      {rutgers,uunet}!ukma!david, david@UKMA.BITNET
<---- 				What does the phrase "Don't work too hard" 
<---- have to do with the decline of the american 'work ethic'?

chip@ateng.uucp (Chip Salzenberg) (09/15/88)

According to stu@gtisqr.UUCP (Stu Donaldson):
>As I said, my solution was to create /bin/test.  Here is a copy,
>it is incredibly simple.
>
>	:
>	# /bin/test
>	if [ $* ]
>	then
>	  exit 0
>	else
>	  exit 1
>	fi

Besides being simple, it is also broken.  :-)  Just imagine trying to
run "test '*' = '*'".  Here's a better implementation:

	:
	# /bin/test
	if [ "$@" ]
	then
	  exit 0
	else
	  exit 1
	fi

-- 
Chip Salzenberg                <chip@ateng.uu.net> or <uunet!ateng!chip>
A T Engineering                My employer may or may not agree with me.
	  The urgent leaves no time for the important.

ditto@cbmvax.UUCP (Michael "Ford" Ditto) (09/16/88)

In article <450@gt-ford.gtisqr.UUCP> uw-nsr!uw-warp!gtisqr!stu@beaver.cs.washington.edu (Stu Donaldson) writes:
>As I said, my solution was to create /bin/test.  Here is a copy,
>it is incredibly simple.
>
>	:
>	# /bin/test
>	if [ $* ]
>	then
>	  exit 0
>	else
>	  exit 1
>	fi

This script will not work correctly with arguments that are empty or
contain special characters.  (For example:

	if /bin/test "$foo" = ""; then exit; fi

would not work because the $* would expand to only "$foo =").  Use of
"$@" instead of $* fixes this, and here's another way of implementing
the /bin/test script:

	[ "$@" ]

Yes, that's right, just that one line will do it.
-- 
					-=] Ford [=-

	.		.		(In Real Life: Mike Ditto)
.	    :	       ,		ford@kenobi.cts.com
This space under construction,		...!ucsd!elgar!ford
pardon our dust.			ditto@cbmvax.commodore.com

maart@cs.vu.nl (Maarten Litmaath) (09/17/88)

In article <1988Sep15.084528.16726@ateng.uucp> chip@ateng.UUCP (Chip Salzenberg) writes:
\Here's a better implementation:
\
\	:
\	# /bin/test
\	if [ "$@" ]
\	then
\	  exit 0
\	else
\	  exit 1
\	fi

Here's a better implementation:

	:
	exec [ "$@" ]
-- 
    Alles klar,                       |Maarten Litmaath @ Free U Amsterdam:
                   Herr Kommissar?    |maart@cs.vu.nl, mcvax!botter!maart