100

I have a bash script that I want to remove files from various directories. Frequently, they won't be there because they weren't generated and that's fine. Is there a way to get the script not to report that error, but if rm has some other output to report that?

Alternately, is there a better command to use to remove the file that'll be less noisy?

8 Answers 8

156

Use the -f option. It will silently ignore nonexistent files.

From man rm:

   -f, --force
          ignore nonexistent files and arguments, never prompt

[The "never prompt" part means that (a) -f overrides any previously specified -i or -I option, and (b) write-protected files will be deleted without asking.]

Example

Without -f, rm will complain about missing files:

$ rm nonesuch
rm: cannot remove ‘nonesuch’: No such file or directory

With -f, it will be silent:

$ rm -f nonesuch
$
1
  • 6
    Oh, I new that didn't prompt for removal, didn't realize it also ignored nonexistents. I totally skipped over that when looking at man. :-) Thank you. I'll mark this as the answer soon as I'm allowed.
    – flickerfly
    Apr 29, 2016 at 18:54
13

If your requirement is that rm does not complain about missing files, but that you also want any other output from rm, my suggestion would be to first test for the target file's existence, and only call rm (without the -f flag) if the file actually exists.

# rest of script
# ...
[ -e "$file" ] && rm "$file"
# ...
# rest of script

Calling rm -f on a file that, for example, doesn't have user-write permissions, will remove the file and also not emit the normal prompt for that scenario.

In case you wanted to use the same idea with multiple files, I would create a function definition, like:

qrm() {
  for f
  do
    [ -e "$f" ] && rm "$f"
  done
}

Use it like: qrm file1 file2-does-not-exist *.txt etc here

2
  • 3
    It's worth being aware of the very slight chance of a race condition where the file is deleted (or created) between the test and the removal, but I can't imagine that being relevant in any typical situation where one would be using a shell script.
    – David Z
    May 1, 2016 at 7:43
  • @DavidZ How could that happen? This tests if something exists and then if that succeeds, removes it so it has to get back a response before the removal starts.
    – flickerfly
    Apr 7, 2021 at 13:13
9

You stated that you still want to see other output from the rm command when you run it, but using the -f option will suppress those. You will need to filter STDERR for what you want, which is a little tricky, given you want everything else to show.

You will want to use a command like this:

rm -f filename 3>&1 1>&2 2>&3 3>&- | grep -v 'No such file or directory'

Command explained:

  • -f argument is to force through and not prompt for confirmation or errors
  • 3>&1 1>&2 2>&3 3>&- is to switch around STDOUT and STDERR for filtering (you can read more about this here if wanted
  • | grep -v 'No such file or directory' is filtering out the message you do not want to see

Now, if you just wanted to suppress error messages entirely, you could run the following command:

rm filename 2> /dev/null

This command redirects STDERR to /dev/null so you will not see it when you run the command.

1
  • 1
    (AFAICS) rm without -v never outputs to stdout, only stderr, so in this case you could just 2>&1 | grep without the dance which is useful more generally, Apr 30, 2016 at 11:20
5

This is a hack, but you could always touch the file about to be removed. If it doesn't exist, it will be created so rm can remove it.

1
  • I like this, except for the performance - how costly is it to touch several K's of files as opposed to only deleting the ones that don't exist?
    – Dani_l
    May 1, 2016 at 15:12
5

As an alternative, you can use the find command with the -delete option. This will (obviously) only delete the files it finds so it never warns if none are. An example might be:

find /var/log/triffids/ -name "*.log" -mtime 30 -delete

which would search the /var/log/triffids/ directory and delete all files with the .log suffix which have not been modified for more than 30 days.

It is always a good idea to run these commands without the -delete option first, to make sure it's finding the files you expect.

1
  • I like this option and will consider a change. Thanks for sharing it.
    – flickerfly
    Apr 30, 2016 at 18:19
3

Check the --force (-f) option of rm:

-f, --force

ignore nonexistent files and arguments, never prompt

0

You can use -f as it will, according to the man page:

Attempt to remove the files without prompting for confirmation, 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. also remember The -f option overrides any previous -i options.

rm -f xyz-directory

will not prompt you anything, and will do exactly what you want.

-1

There are two main ways: If you add the -f option, it will not show the "doesn't exist" error and two: (works for almost any command) instead of just doing "thecommand" do "thecommand 2>/dev/null" where "thecommand" is the command you're doing.

1
  • 1
    I was avoiding the piping because I don't want to loose other errors that might come up. I don't know what they would be.
    – flickerfly
    Apr 29, 2016 at 18:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .