I'm writing a makefile that will clean up some useless files at the end of the compilation. If a target has already been made, it will of course skip that target and the useless file may not be there. So if I do this:
rm lexer.ml interpparse.ml interpparse.mliI may get errors because one of the files doesn't exist. Is there any way to tell rm to ignore these files?
In reading the man page, I see the following option:
-f Attempt to remove the files without prompting for confirma- tion, regardless of the file's permissions. If the file does not exist, do not display a diagnostic message or modify the exit status to reflect an error. The -f option overrides any previous -i options.That sounds like almost what I want, but I'm not really sure about the permissions part. Is there a way to do this?
414 Answers
The -f option is definitely what you want to be using.
The confirmation about file permissions it refers to is this:
$ touch myfile
$ chmod 400 myfile
$ rm myfile
rm: remove write-protected regular empty file `myfile'?So rm will warn you if you try to delete a file you don't have write permissions on. This is allowed if you have write permissions on the directory but is a little weird, which is why rm normally warns you about it.
Another solution is this one:
Just add an OR-statement after your command:
rm -rf my/dir || trueThis way, when statement #1 fails (throws error), run statement #2, which is simply true.
I'm way late to the party, but I use this all the time. In a makefile, add - to the beginning of a line to ignore the return value of that line. Like so:
-rm lexer.ml interpparse.ml interpparse.mli6
If you don't want to use the -f option, an alternative is:
rm filethatdoesntexist 2> /dev/null || trueThis will just keep errors from being printed.
1If you find some way to glob the file names, rm won't complain if it can't find a match. So something like lexer.m* interpparse.*, etc. should work for you (be careful you're not deleting too much, of course). Also, -f is a perfectly reasonable way to go, as long as you're not hoping that file permissions will save you from deleting a file you didn't want to - if you don't want to delete it, don't put it in the list.
The -f option means that you will not be prompted if something is not as expected. It does not mean that permissions are not taken into account.
If you have not enough privileges to remove a file, it won't be removed.
BUT, if you have enough privileges to change privileges, you file will be removed. This is the case when you are the owner of a file with readonly permissions for owner (-r--------). As owner, you can chmod u+w, then remove it: rm -f will remove that file.
Maybe could help a line similar with:
touch fakefile.exe fakefile.o && rm *.o *.exeI know that this is not very smart, but it does the job.
test to see if the file exists first, if it does, then pass it to rm. Then the errors from rm will be meaningful. -f or ignoring the error message is typically more encompassing than what a person wants. -f might do things you don't want done.
if [ -f lexer.ml ]; then rm lexer.ml
fiadd more test clauses if there are more files you want to be sure exist.
An alternative:
RmIfIsFile() { for f in "$@"; do [ -f $f ] && rm $f; done; }; RmIfIsFile lexer.ml interpparse.ml interpparse.mliToo bad Makefiles can't share shell function definitions across lines.
2Here's what I use in shell scripts. It hides the error message and error code.
rm doesnotexist 2> /dev/null || echo > /dev/null 1 you can touch the files before you rm them. that would create them if they don't exist :-)
touch lexer.ml interpparse.ml interpparse.mli
rm lexer.ml interpparse.ml interpparse.mli write rm -rf ppp>/dev/null 2>&1you newer get error message Problem occurs, if error generate not to STDERR 2 but STDOUT 1... It's take place when command generate not error but warning.
You need to set filter and remove this message. But this case is ordinary.
Simply supress the error message which is built-in function in rm command:
rm -f -- lexer.ml interpparse.ml interpparse.mliIt will remove the file if exists, otherwise it doesn't give any error message.
Simply check IF the directory/file already exists:
to remove a file
file=path/to/the/file/to/copy && [ -f "${file}" ] && rm ${file} destination/path/hereto remove a directory
dir=path/to/the/dir/to/copy && [ -d "${dir}" ] && rm -r ${dir} destination/path/here
NOTE:
the spaces before/after the square brackets are mandatory, not to break the above commands.
REFERENCES:
1