There are several issues.
Passing a $ sign in a Makefile to the shell
You want to run the command
rm $(find . -type f -executable)
to let the shell do the command substitution. To do this you need to write
clean:
rm $$(find . -type f -executable)
with the dollar doubled as Make itself uses $
.
If your version
Handing the case where there is nothing to "clean"
If the output of find
supports itis empty, then after command substitution
rm $(find . -type f -executable)
becomes
rm
and the typical rm
command complains that you haven't told it would be betterwhat to remove. One way to address this is to use xargs
to process the output of find
. It takes the output of find
and if there is any it splits it into blocks and runs rm.
clean:
find . -type f -executable -delete| xargs rm
Handling arbitrary characters in filenames
as it avoids problems withUnix filenames are made up of components separated by /
characters like. The components themselves can be any sequence of characters except /
and NUL. In particular a component can include newline characters, spaces in, tabs, *
.
For the command substitution case (rm $(find . -type f -executable)
) case the shell will process the output of find. So white-space characters will cause word splitting, *
characters will cause filename "globbing" to take place etc. For reasonable implementations of xargs
this is avoided.
If filenames begin with -
then rm
might consider them to be options to the command. The simple way to avoid this is to add --
to the command to indicate "end of options".
The major remaining issue is newlines. xargs
splits the input on newlines, so if you have thema file called abc\ndef
then find
will output
abc
def
and xargs
will invoke rm
with 2 filenamesabc
and def
.
To work around this, tell both find
and xargs
to use the 1 character (NUL) that can't appear in your filenames as the deliminator rather than newline.
clean:
find . -type f -executable -print0 | xargs -0 rm --
Best solution, if your find
supports it
clean:
find . -type f -executable -delete
Here you have find directly removing the files, if any. It is more efficient as it doesn't need to start additional processes. There are no shells or xargs processes to need to escape characters. No special characters to tell make
to process. Handles the "no files to delete" case correctly.