Home / Alt manpages / rm(1)

  • rm(1)
  • User command
  • linux

Remove Files Safely with GNU rm

Everyone has typed rm against the wrong path at least once. This guide is a repeatable workflow for removing files and empty directories without recursive deletion catching you out. Examples match GNU coreutils coreutils 9.4-3ubuntu6.3 and take about ten minutes.

You need a shell and permission to change whatever you intend to remove. Ordinary files in your own working area need no sudo; a permission error might need an administrator, but elevated privileges never make a risky path safer.

Warning

Rm removes directory entries immediately. There is no general undo, and the manual only says recovery may be possible with sufficient expertise or time. Confirm the exact path before every destructive command, and keep a backup or move anything important somewhere recoverable first.

1. Confirm the installed command

Check which implementation and version your shell will run. Both of these are read-only:

$ command -v rm
/usr/bin/rm
$ rm --version | head -1
rm (GNU coreutils) 9.4

GNU rm removes named files by default and will not touch a directory. It accepts several operands at once, which means a typo in a shared prefix can hit more paths than you meant. Treat every operand as part of the deletion plan, not an afterthought.

Checkpoint

If command -v rm turns up an unexpected wrapper or alias, look at it before continuing. The examples here assume plain rm with no extra options baked in.

2. Remove one known file

Look at the exact path first, then remove it without bolting on options you do not need:

$ ls -l -- /path/to/old-report.txt
$ rm -- /path/to/old-report.txt
$ test ! -e /path/to/old-report.txt && echo 'removed'
removed
  • Use -- whenever a path comes from a variable or might start with a hyphen; it marks the end of options.
  • The final test only confirms absence. It does not, and cannot, recover the content.

For a batch of known files, list every path explicitly:

$ printf '%s\n' /path/to/cache-a /path/to/cache-b
/path/to/cache-a
/path/to/cache-b
$ rm -- /path/to/cache-a /path/to/cache-b

Never run an unreviewed wildcard like rm -- /path/to/cache/* against a directory you have not inspected. The shell expands that wildcard before rm even starts, so it can quietly select more than you had in mind.

3. Add a prompt when a mistake would hurt

  • -i prompts before every removal. Use it interactively when you want to eyeball each target.
  • -I is a lighter guard. GNU rm asks once when more than three files are supplied, or when recursive removal is requested. It only helps if you actually stop and read the prompt.
  • -f means force: ignore missing operands, never prompt. Useful in a well-tested cleanup script, but it removes your last chance to catch a wrong path. Do not combine it with a command you have not run against a harmless fixture first.
$ rm -i -- /path/to/old-report.txt
rm: remove regular file '/path/to/old-report.txt'? y

4. Remove an empty directory

-d removes an empty directory and fails rather than deleting contents:

$ find /path/to/empty-dir -mindepth 1 -maxdepth 1 -print
$ rm -d -- /path/to/empty-dir
$ test ! -e /path/to/empty-dir && echo 'directory removed'
directory removed

Checkpoint

find prints nothing when the directory is genuinely empty. If it prints a path, stop and look at it. If the directory is not empty, -d leaves it alone and reports the failure instead of guessing what you meant.

5. Treat recursive deletion as its own decision

Warning

-r, -R and --recursive remove a directory and everything in it, and that is irreversible for practical purposes. Inspect the tree first and use the one-time guard:

$ find /path/to/disposable-tree -mindepth 1 -maxdepth 2 -print
$ rm -I -r -- /path/to/disposable-tree
rm: remove 1 argument recursively? y
$ test ! -e /path/to/disposable-tree && echo 'tree removed'
tree removed
  • Confirmation wording and count vary by version and tree. A non-affirmative answer just aborts.
  • Crossing a mount you should not? Add --one-file-system to skip other file systems during recursive traversal. That is a boundary check, not a backup.
  • Never touch --preserve-root. GNU rm protects / by default, and --no-preserve-root exists only for unusual, tightly controlled administrative cases. Defeating it turns a path mistake into a host-wide incident.

6. Handle a filename that looks like an option

A file named -draft.txt must never be handed to rm as a bare argument. Use -- or a path with a directory component instead:

$ rm -- -draft.txt
$ rm ./-draft.txt

Inspect it first with ls -l -- -draft.txt or similar. The same caution applies to any name a script or another user hands you; quote shell variables when they are meant to be one path:

$ target='/path/to/file with spaces.txt'
$ ls -l -- "$target"
$ rm -- "$target"

7. Diagnose a failed removal

Add -v to have every successful removal reported:

$ rm -v -- /path/to/old-report.txt
removed '/path/to/old-report.txt'
  • Missing file, non-zero status: if that is an expected outcome in an idempotent script, -f suppresses the error, but check your path construction before reaching for it.
  • Permission failure: check ownership and mode with ls -ld on the file and its parent directory. Ask an administrator only once the intended path is verified; sudo rm is not a repair for uncertainty.

There is no matching rm command to bring data back. If you deleted the wrong path, stop writing to that file system immediately and use your backup or recovery process. For genuinely sensitive data, ordinary rm is not a secure-erasure method either: the manual points to shred(1) for stronger assurance, though the underlying storage and file system still need their own separate assessment.

Done means

  • Confirmed the installed command is GNU coreutils 9.4.
  • Inspected every path before removal and used -- on every operand.
  • Used -d for empty directories and reserved -r for a tree you had already inspected.
  • Know that -f suppresses prompts and errors, not risk.
  • Have a backup or recovery route for anything that actually matters.