opscape

Files and directories

rm

Delete files, and with -r whole directory trees. There is no undo.

rm [OPTION...] FILE...

12 of 12 examples run in Debian 13.7 on 2026-10-31 · coreutils 9.7-3 · manual: rm(1)

rm removes directory entries. On the command line there is no trash can: once the last link to a file is gone and no process has it open, the space is reused. Treat every rm as final.

By default rm only deletes files. -r (recursive) is needed for directories and everything in them, and -f (force) suppresses errors about missing files and stops all prompting. rm -rf is therefore the most destructive everyday command there is: double-check the path, especially when it contains a variable.

Interactive options are a seatbelt: -i asks before every file, -I asks once before deleting more than three files or recursing. To remove only empty directories, rmdir is safer.

Examples

Delete a file

rm todo.txt
ls todo.txt
outputexit 2
ls: cannot access 'todo.txt': No such file or directory

rm prints nothing when it succeeds. The ls afterwards fails because the file is gone.

Delete files matching a pattern

Setup run before this example
touch report1.bak report2.bak notes.bak
rm -v *.bak
explain
output
removed 'notes.bak'
removed 'report1.bak'
removed 'report2.bak'

The shell expands *.bak into the three names; -v makes rm report each removal. Run ls *.bak (or echo rm *.bak) first to see exactly what a pattern matches.

Removing a file that does not exist

rm nosuch.txt
explain
outputexit 1
rm: cannot remove 'nosuch.txt': No such file or directory

Without -f, a missing file is an error with exit status 1.

Ignore missing files with -f

rm -f nosuch.txt
echo "exit status: $?"
output
exit status: 0

-f makes a missing file a non-event, which is what cleanup code in scripts wants: rm -f "$tmpfile" succeeds whether or not the file was ever created.

rm refuses directories without -r

rm logs
explain
outputexit 1
rm: cannot remove 'logs': Is a directory

Directories need -r. This is deliberate: deleting a directory deletes everything below it.

Delete a directory and everything in it

rm -rv logs
explain
output
removed 'logs/error.log'
removed 'logs/app.log'
removed 'logs/app.log.1'
removed directory 'logs'

-r descends into the directory, deletes the files, then the directory itself. -v shows the order: contents first, logs last.

Ask before each deletion

rm -i todo.txt notes.txt
ls todo.txt notes.txt
outputexit 2
rm: remove regular file 'todo.txt'? rm: remove regular file 'notes.txt'? ls: cannot access 'todo.txt': No such file or directory
notes.txt

-i asks for each file and reads the answer from standard input. Here the input answered y for todo.txt and n for notes.txt, so only notes.txt survives. The prompts have no trailing newline, so they run together on one line.

Delete a file whose name starts with a dash

Setup run before this example
touch -- -draft.txt
rm -draft.txt
rm -- -draft.txt && echo removed
output
rm: invalid option -- 'a'
Try 'rm ./-draft.txt' to remove the file '-draft.txt'.
Try 'rm --help' for more information.
removed

rm -draft.txt is parsed as a cluster of options (-d, -r, -a, ...) and fails on the unknown -a; GNU rm even suggests the fix. -- ends option parsing, so everything after it is a file name. rm ./-draft.txt works too.

Delete a file with spaces in its name

rm file with spaces.txt
rm "file with spaces.txt" && echo removed
output
rm: cannot remove 'file': No such file or directory
rm: cannot remove 'with': No such file or directory
rm: cannot remove 'spaces.txt': No such file or directory
removed

Unquoted, the name is split into three arguments, none of which exists. Quoted, it is one.

Files you do not have write permission on

Setup run before this example
chmod a-w todo.txt
rm todo.txt && echo removed
explain
output
removed

What matters for deleting is write permission on the directory, not on the file. In a terminal, rm would first ask "remove write-protected regular file?"; with no terminal on standard input, as here, it just removes it.

Guard against an empty variable

dir=""
rm -rf "${dir:?is empty}/cache"
outputexit 127
/bin/bash: line 2: dir: is empty

With an empty dir, rm -rf "$dir/cache" would target /cache. ${dir:?...} makes bash print the message and abort before rm ever runs; a non-interactive bash (a script) exits on the spot, here with status 127.

Common pitfalls

  • rm -rf $dir/ with an unset dir becomes rm -rf /. Quote variables and use ${dir:?}, or set -u (see Strict mode and its caveats).

  • A stray space is fatal: rm -rf ./build /* deletes ./build and then everything matching /*. Read the command again before pressing Enter.

  • Deleting a large log file that a process still has open frees no space until the process closes it; lsof +L1 lists such files. Truncate it instead with : > file or truncate -s 0.

  • rm cannot really erase data: blocks remain on disk until overwritten. shred exists but is unreliable on SSDs and journaling or copy-on-write filesystems.

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • GNU rm refuses rm -rf / unless you add --no-preserve-root; modern BSD/macOS rm also refuses to remove /.

  • -I (prompt once) and --one-file-system are GNU options; check your system's man page on BSD/macOS.

Options worth knowing

A selection, described in our own words. For the full list, see rm(1) or rm --help.

OptionWhat it does
-r, --recursiveRemove directories and their contents.
-RSame as -r.
-f, --forceIgnore missing files and never prompt.
-iPrompt before every removal.
-IPrompt once before removing more than three files or recursing.
-v, --verbosePrint each file as it is removed.
-d, --dirAlso remove empty directories, like rmdir.
--interactive[=WHEN]Prompt never, once or always.
--one-file-systemWith -r, skip directories on other filesystems.
--preserve-rootRefuse to operate on / (the default).
--no-preserve-rootAllow recursive removal of /; almost never what you want.

Related