Where to start First steps track · 15 stages
Linux Labs

rm — remove files and directories

6 min Ubuntu 24.04 · GNU coreutils 9.4

The rm command deletes files and directories at once, with no trash; -i and -I ask first, -r removes a tree.

Cheat sheet

9 commands Printable version
  • rm notes.txt delete a file
  • rm -i *.log ask about every file
  • rm -I *.log ask once if there are more than three
  • rm -r old-project a directory with everything inside
  • rm -rf build/ no prompts, no errors about missing files
  • rm -d empty-dir an empty directory (like rmdir)
  • rm -v *.tmp print each removal
  • rm -- -file.txt a name that starts with a dash
  • ls *.log && rm -i *.log look first, then delete

Overview

rm (remove) deletes file names from a directory. There's no trash in the terminal: a deleted file isn't kept anywhere, and there's no "undo" command.

text
student@ubuntu:~$ rm -v draft.txt
removed 'draft.txt'
student@ubuntu:~$ rm old-project
rm: cannot remove 'old-project': Is a directory
student@ubuntu:~$ rm -rv old-project
removed 'old-project/readme.md'
removed directory 'old-project'

rm deletes a directory only with -r (recursively, with its contents) or, if it's empty, with -d. -f (force) drops prompts and errors about missing files: rm -rf silently deletes everything it can.

Deleting needs write permission on the directory that holds the file. The file's own permissions decide only one thing: whether rm asks before removing a write-protected file.

Options

7

Full list — man rm. In practice -i, -I, -r, -f, -v are enough.

Option What it does Example
-r Remove a directory with everything inside (same as -R). rm -r old-project
-f Never prompt and stay silent about missing files. dangerous rm -rf build/
-i Prompt before every removal. rm -i *.log
-I Prompt once — when removing more than three files or recursively. rm -I *.log
-v Print each removal — removed 'x'. rm -v *.tmp
-d Remove an empty directory. rm -d empty-dir
--one-file-system When removing recursively, skip directories on other mounted filesystems. rm -r --one-file-system /mnt/old

Nothing found. Try a shorter query.

Recipes

4

Check a pattern before deleting

bash
ls -d /var/tmp/app/*.cache     # what the pattern matches
rm -v /var/tmp/app/*.cache     # the same, now delete

The shell expands the pattern (see globbing), so ls with the same pattern shows exactly the list rm will get.

Delete old files by age

bash
find /var/log/app -name '*.log' -mtime +30 -print   # list first
find /var/log/app -name '*.log' -mtime +30 -delete  # then delete

rm can't select by date or size — that's find's job.

Guard rm -rf against an empty variable

bash
rm -rf -- "${BUILD_DIR:?}"/*   # empty variable → error, not /*

${VAR:?} stops the command if the variable is empty or unset.

Delete a file with a strange name

bash
rm -- '-rf'            # a name with a leading dash
rm -i ./*' '*          # names with spaces — with confirmation
ls -li                 # the inode number in the first column
find . -inum 1234567 -delete   # delete by inode number

Troubleshooting

6

rm: cannot remove 'dir': Is a directory

The argument is a directory. rm -d removes an empty one, rm -r one with contents (look inside first: ls -R dir).

rm: cannot remove: Permission denied

You can't write to the directory holding the file. Check ls -ld $(dirname path). System files are removed with sudo rm, but first make sure no package or service needs the file.

rm: remove write-protected regular file?

The file lacks w. rm asks instead of refusing: answer y, or delete with -f if you're sure.

rm: cannot remove: Operation not permitted

The file has the immutable attribute (lsattr file shows i), or it's someone else's file in a sticky directory like /tmp. Clear the attribute with sudo chattr -i file.

Disk space wasn't freed

A process still has the file open: the name is gone, the data isn't. Find the holder with sudo lsof +L1 — see lsof and disk-usage. The space comes back when that process restarts.

Argument list too long

The pattern matched too many files for one command. Delete with find: find . -name '*.tmp' -delete.

Danger zone

2

There's no recovery

rm doesn't move files to a trash. If a file isn't in a backup or in git, consider it gone. Before a mass delete run ls with the same pattern, or use rm -I.

rm -rf with a stray space or an empty variable

rm -rf / tmp/build (an extra space) asks to delete the root. A built-in check guards / (it is dangerous to operate recursively on '/'), but /*, ~ and . have no guard: rm -rf "$DIR"/* with an empty $DIR becomes rm -rf /*. Write "${DIR:?}" and read the whole command before pressing Enter.

See also

  • ls — see what the deletion will hit.
  • find — delete by age, size or name across the tree.
  • mv — move a file aside instead of deleting it.
  • globbing — how the shell expands *.log.
  • lsof — who holds a deleted file and its disk space.
  • files-basics — an overview of the basic file commands.
Loading…