How to prevent rm from reporting that a file was not found?
Asked Answered
C

6

226

I am using rm within a BASH script to delete many files. Sometimes the files are not present, so it reports many errors. I do not need this message. I have searched the man page for a command to make rm quiet, but the only option I found is -f, which from the description, "ignore nonexistent files, never prompt", seems to be the right choice, but the name does not seem to fit, so I am concerned it might have unintended consequences.

  • Is the -f option the correct way to silence rm? Why isn't it called -q?
  • Does this option do anything else?
Corinthians answered 20/4, 2012 at 13:43 Comment(2)
you don't want to use -f, it removes file you marked as read only.Donetsk
@pizza, only if you marked them read-only badly. If you use the permission system correctly, rm can't remove a read-only file, even with -f; and if you're not doing it in a way the operating system actually enforces, is it really read-only at all?Megass
P
268

The main use of -f is to force the removal of files that would not be removed using rm by itself (as a special case, it "removes" non-existent files, thus suppressing the error message).

You can also just redirect the error message using

$ rm file.txt 2> /dev/null

(or your operating system's equivalent). You can check the value of $? immediately after calling rm to see if a file was actually removed or not.

Pellmell answered 20/4, 2012 at 16:58 Comment(6)
--f is valid for GNU Coreutils rm, but only because it happens to be a unique abbreviation for --force. The short form -f is clearer and more portable.Bedard
Not sure I even realized that. --f here is just a typo for -f.Pellmell
what does the 2 in 2> do?Anglonorman
@Maverick It redirects any messages sent to stderr to /dev/null instead of sending them to the terminal.Hardesty
It doesn’t print the error in terminal, but yet it stops the code execution like fatal error, so it doesn’t really solving the problem…Uncharitable
@Uncharitable That's not a problem with rm. rm will remove what files it can (if you specified a mix of existing and non-existing files as arguments) before exiting with a non-zero exit code. If you are running your script with set -e (something I don't advise), you'll need to "guard" the command with something like if rm ...; then ...; fi to detect if there was an error or not without causing the shell itself to exit.Pellmell
H
99

Yes, -f is the most suitable option for this.

Hexapartite answered 20/4, 2012 at 13:45 Comment(2)
Some systems will prompt you when room even with -f till you use backslash.Chekhov
@vimdude: It's not "some systems"; that behavior indicates that you have a shell function or alias that maps rm to rm -i.Bedard
H
36

-f is the correct flag, but for the test operator, not rm

[ -f "$THEFILE" ] && rm "$THEFILE"

this ensures that the file exists and is a regular file (not a directory, device node etc...)

Humanist answered 12/6, 2013 at 20:47 Comment(6)
However, this has a race condition, and should not be used in production scripts.Bodrogi
I believe what @Bodrogi is pointing out is that the "-f" test and the file removal could complete in any order. Another way to do it is: if [ -f "$THEFILE" ]; then rm "$THEFILE"; fi, which makes the test and the file removal steps explicitly sequential.Morphine
@Morphine that code does the same exact thing with more verbose syntax ... && != & ... The test will always happen before rm but a separate process could technically (though very unlikely) delete it before rm runs (while the shell code after the test is being interpreted).Humanist
technosaurus - ooops, you're right. What do you think is the best answer to @mmlac's question?Morphine
@Morphine This question currently has two answers with more than 40 upvotes; what makes you think either of those are not acceptable solutions to this question? My vote goes to "simply use rm -f" because discarding error messages could mask other errors. This answer is misleading in implying that there is something wrong with using rm -f and that somebody made a mistake and intended to use test -f.Bodrogi
And just to confirm, the race condition is that something could remove the file between test and rm. There is no way rm could execute before test here. Looking before you leap isa common mistake in concurrent programming -- you can't trust the result of the "look" any longer when you actually "leap"; the solution to that is to use locking or atomic operations. Which is precisely why you want rm -f, which is an example of the latter.Bodrogi
C
21

\rm -f file will never report not found.

Chekhov answered 24/10, 2012 at 16:55 Comment(5)
The -r is unnecessary and dangerous.Rapper
I assumed many files or directories. Reread user's request and you're right he was asking for files only. So corrected my answerChekhov
What is the backslash before the rm doing?? please guys I need an answer to that. On windows cygwin's make version 4.1 can't deal with \rm while 3.75 works just fine.Sesquipedalian
@AymanSalah The backslash in this context would escape any function or alias wrapping the real rm (as was popular on some sites in the early 1990s to prevent beginners from removing stuff and then calling up the sysadmin to get their files back).Bodrogi
Thank you - this solved my issue.. apparently the exit code allows for chaining using && while without -f it breaks once the file is not found.Grabowski
R
9

As far as rm -f doing "anything else", it does force (-f is shorthand for --force) silent removal in situations where rm would otherwise ask you for confirmation. For example, when trying to remove a file not writable by you from a directory that is writable by you.

Resht answered 20/4, 2012 at 16:51 Comment(0)
E
-11

I had same issue for cshell. The only solution I had was to create a dummy file that matched pattern before "rm" in my script.

Elba answered 28/5, 2014 at 17:53 Comment(2)
Was that really the only solution? Did you try rm -f or rm filename >&/dev/null?Bedard
perhaps it's not the only solution, but it is sensible and readable and has no side effects.Cigar

© 2022 - 2024 — McMap. All rights reserved.