216

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?
Village
  • 22,513
  • 46
  • 122
  • 163
  • 5
    you don't want to use -f, it removes file you marked as read only. – pizza Apr 20 '12 at 21:29
  • @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? – Charles Duffy Mar 07 '22 at 20:52

6 Answers6

265

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.

dreftymac
  • 31,404
  • 26
  • 119
  • 182
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 3
    `--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. – Keith Thompson May 28 '14 at 18:09
  • 1
    Not sure I even realized that. `--f` here is just a typo for `-f`. – chepner May 28 '14 at 18:27
  • 6
    what does the 2 in `2>` do? – Dan Aug 20 '18 at 15:38
  • @Maverick It redirects any messages sent to stderr to /dev/null instead of sending them to the terminal. – Benjamin Nolan Dec 19 '18 at 13:05
  • 3
    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… – Ido Dec 12 '21 at 07:39
  • @Ido 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. – chepner Dec 12 '21 at 14:37
96

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

Satya
  • 8,693
  • 5
  • 34
  • 55
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...)

technosaurus
  • 7,676
  • 1
  • 30
  • 52
  • 7
    However, this has a race condition, and should not be used in production scripts. – tripleee Jul 31 '14 at 06:38
  • I believe what @tripleee 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. – robla Jan 10 '19 at 19:56
  • 3
    @robla 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). – technosaurus Jan 10 '19 at 21:56
  • technosaurus - ooops, you're right. What do you think is the best answer to @mmlac's question? – robla Jan 11 '19 at 01:54
  • @robla 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`. – tripleee Jan 11 '19 at 04:45
  • 3
    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. – tripleee Jan 11 '19 at 04:50
20

\rm -f file will never report not found.

vimdude
  • 4,447
  • 1
  • 25
  • 23
  • 6
    The -r is unnecessary and dangerous. – mahemoff Jun 11 '13 at 21:04
  • 1
    I assumed many files or directories. Reread user's request and you're right he was asking for files only. So corrected my answer – vimdude Jun 12 '13 at 20:12
  • 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. – Ayman Salah Jul 24 '17 at 10:47
  • 3
    @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). – tripleee Jan 11 '19 at 04:41
  • 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. – Igor May 29 '20 at 12:45
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.

Idelic
  • 14,976
  • 5
  • 35
  • 40
-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.