Skip to main content

Linux command: rm

11 July 2026

Of all the everyday Linux commands, rm is the one that deserves a moment of respect before you press Enter. It deletes files, it deletes folders full of files, and it does all of this instantly, silently, and with no trash can to fish things out of afterwards. There is no undo. Yet the biggest surprise about rm is that it does not really "erase" anything at all: it removes a name, and the data often lingers on the disk long after you thought it was gone. Learning rm properly means learning what deletion actually is in Linux, and exactly where the danger lives.

1. The Basics

The job of rm is to remove a file. You give it one or more names, and it deletes them from the directory they live in. The original is gone from your view at once, and unlike a desktop file manager, rm does not move anything to a trash folder first. When it finishes, the file is simply no longer there.

Here is the mental model worth holding on to, and it is the same idea that makes mv so fast. A file's data lives on the disk, and its name lives in a directory as a small entry pointing at that data. What rm actually does is delete that directory entry. It does not scrub the bytes off the disk. It removes the link between a name and its data, and the system frees the data only once nothing points at it any more. This is why the manual describes rm as a tool to "remove (unlink) files".

The command reads left to right: every argument is a file you want removed.

$ rm oldfile.txt

The command that feels final, because it is. Behind those two letters sits one clean idea: deleting a file does not erase its data, it removes a name that pointed at the data, and lets the system reclaim the space later.

This article starts with removing a single file and builds up to deleting whole directory trees, the safety flags that stop a disaster, why rm -rf / is now refused by default, why a deleted file can still be recovered, and the surprising fact that removing a name does not always delete the file. By the end you will know not only how to delete a file, but exactly when rm is about to delete far more than you meant.

The right mental model: rm does not wipe data, it unlinks a name. The danger is not that it works slowly or leaves traces; the danger is that it works instantly, without asking, and there is no way back.

Back to top

2. Where the Name Comes From

The name rm is simply short for remove. As with most early Unix commands, there is no hidden meaning; the two letters are the first and last consonants of the word.

rm  =  ReMove

Early Unix was typed on slow teletype terminals that printed every character onto paper, so short command names saved both typing and ink. That is why the command is rm and not remove or delete. The same instinct gave us cp (copy), mv (move), and ls (list): a whole vocabulary of two-letter verbs.

It is worth noticing the word that was chosen. The command is not called delete or erase, and that is not an accident. Underneath, rm calls a system function named unlink(), and "unlink" is a far more honest description of what happens: a link between a name and some data is broken, not the data itself. There is even a separate low-level command called unlink that removes exactly one name and nothing more. Keep the word "unlink" in mind; it explains the most surprising behaviour of rm later in this article.

Back to top

3. A Short History

The rm command is one of the original Unix tools. It shipped in Unix 1st Edition at Bell Labs in 1971, alongside cp, mv, and cat, and it has been present on every Unix-like system since: Linux, macOS, the BSDs, Solaris, and AIX. The core idea, "remove a name and let the space be reclaimed", has not changed in over fifty years.

What has changed is how much rm tries to protect you from yourself. The early command did exactly what you told it, including the infamous rm -rf / that would walk the entire filesystem and delete everything it could reach. Modern GNU rm refuses that particular command by default, a safety net added in the mid-2000s after decades of hard-won lessons.

EraMilestone
1971 rm ships in Unix 1st Edition at Bell Labs
1980s BSD and System V add interactive (-i) and recursive (-r) removal
1990s GNU coreutils rm becomes the standard version on Linux
2006 GNU rm refuses to act on / by default (--preserve-root) and gains the gentler -I prompt
2010s coreutils adds --one-file-system to keep a recursive delete from crossing into mounted disks

There are two families you will meet in practice. Most Linux systems run the GNU coreutils version of rm. macOS and the BSDs ship the BSD version. They agree on the everyday flags such as -i, -f, -r, and -v. The differences are in the extras: the -I "prompt once" flag, --one-file-system, and the --preserve-root safety are GNU features that BSD spells differently or lacks. This article uses the GNU version, which is what you will find on almost every Linux server.

Back to top

4. Simple Use Cases

4.1 Removing a Single File

Give rm a filename and it removes that file. In the examples below, the line that starts with $ is what you type; a command that prints nothing simply succeeded, which is the normal Unix way of saying "all good".

$ rm notes.txt
$ ls
report.txt  todo.txt

The file notes.txt is gone from the listing immediately. There is no confirmation and no summary, because in the Unix tradition silence means success.

4.2 Removing Several Files at Once

You can pass as many names as you like, and rm removes each one. This is where wildcards become both powerful and dangerous, a point Section 6 returns to.

$ rm draft1.txt draft2.txt draft3.txt
$ rm *.log                    # remove every file ending in .log

The shell expands *.log into the matching filenames before rm runs, so rm never sees the star; it just receives a list of names. That detail matters a great deal once the pattern is broad.

4.3 Asking First: -i

Because there is no undo, the safest habit when deleting by hand is to make rm ask. The -i flag (short for interactive) prompts before every single removal, and it deletes only the files you answer y to.

$ rm -i report.txt
rm: remove regular file 'report.txt'? y

Many systems alias rm to rm -i for the root user for exactly this reason. It turns a silent, instant command into one that gives you a chance to stop.

4.4 Seeing What Happens: -v

The -v flag (short for verbose) prints one line per file removed. On a batch delete this turns a silent operation into a visible list of exactly what disappeared, which is reassuring when a wildcard is involved.

$ rm -v *.tmp
removed 'cache.tmp'
removed 'session.tmp'

The word removed confirms each deletion after the fact. Pairing -v with a recursive delete is a good way to watch a large operation and catch it early if it starts touching the wrong thing.

Back to top

5. Moderate Use Cases

5.1 Removing a Directory: -r

By default rm refuses to remove a directory. This is a deliberate guard rail, because a directory can contain thousands of files. To delete a folder and everything inside it, you add -r (short for recursive), which tells rm to walk down into the directory, remove its contents, and then remove the directory itself.

$ rm project                       # refused
rm: cannot remove 'project': Is a directory
$ rm -r project                    # removes the folder and all its contents

The flag also exists as -R and as the long form --recursive; all three mean the same thing. This is the single most powerful and most dangerous flag rm has, because one short word can erase an entire tree in an instant.

5.2 Ignoring Errors: -f

The -f flag (short for force) does two things: it never prompts, and it stays silent about files that do not exist instead of complaining. It is common in scripts, where you want "make sure this is gone" without an error when it was already missing.

$ rm nonexistent.txt
rm: cannot remove 'nonexistent.txt': No such file or directory
$ rm -f nonexistent.txt            # no error, no output, exit status still success

Be careful: -f is also the flag that switches off every safety prompt, including one you set with an rm -i alias. Combined with -r it becomes rm -rf, the command that deletes a whole tree without a single question. It has its place, but type it deliberately.

5.3 Removing Empty Directories: -d and rmdir

Sometimes you only want to remove a directory if it is already empty, so you cannot accidentally wipe out contents you forgot were there. The -d flag (short for dir) removes a directory only when it holds nothing.

$ rm -d emptyfolder                # succeeds only if emptyfolder is empty
$ rm -d hasfiles
rm: cannot remove 'hasfiles': Directory not empty

There is also a separate command, rmdir (short for remove directory), that does only this and refuses anything else. Using rmdir or rm -d is a quiet safety habit: if the directory turns out not to be empty, the command stops instead of taking everything with it.

5.4 A Gentler Prompt for Bulk Deletes: -I

Prompting before every file with -i becomes tiring on a large delete, and people quickly learn to hammer the y key, which defeats the point. The capital -I flag prompts just once before removing more than three files, or before any recursive delete. It is far less intrusive while still catching the big mistakes.

$ rm -I *.mp4
rm: remove 6 arguments? y

The long form --interactive=WHEN gives you the full choice in one place: never, once (the same as -I), or always (the same as -i). On a shared server, rm -I is a good default for interactive work: it stays out of your way but stops a runaway wildcard.

Back to top

6. Advanced Use Cases

6.1 The Most Famous Danger: rm -rf /

The command that legends are made of is rm -rf /: remove, recursively and forcefully, starting at the root of the entire filesystem. On old Unix it did exactly that and destroyed the system. Modern GNU rm refuses it by default thanks to a built-in guard called --preserve-root.

$ rm -rf /
rm: it is dangerous to operate recursively on '/'
rm: use --no-preserve-root to override this failsafe

That failsafe is on by default; you would have to add --no-preserve-root on purpose to disable it, which is a strong signal that you are about to do something you will regret. There is even a stricter form, --preserve-root=all, which also refuses any argument that sits on a different mounted disk from its parent.

The protection is narrow, though. It guards the literal /, but it does not guard rm -rf /home/olduser or rm -rf . in the wrong directory. The real lesson is not to lean on the failsafe but to read the whole command before running it, especially the path right after -rf.

6.2 Who Is Allowed to Remove a File

This surprises many newcomers: to delete a file you do not need to own it, and you do not need permission to read or write its contents. Because removing a file edits the directory it lives in, the permission that matters is write and execute on the containing directory, not on the file.

$ ls -l
-r--r--r-- 1 root root 42 Jul  7 10:00 owned-by-root.txt
$ rm owned-by-root.txt             # works if you can write the directory,
                                   # even though the file is read-only and root's

If the file itself is write-protected, rm notices and asks for confirmation as a courtesy, but it can still remove it once you agree. The one real exception is a directory with the sticky bit set, such as /tmp. There, only a file's owner (or root) may remove it, which is exactly what stops users on a shared system from deleting each other's files out of /tmp.

6.3 Filenames That Start With a Dash

A file called -rf or -file.txt looks exactly like an option to rm, so the command reads it as a flag and either fails or, worse, does something you did not intend. The fix is the -- marker, which tells rm that everything after it is a filename, not an option.

$ rm -- -file.txt                  # everything after -- is treated as a name
$ rm ./-file.txt                   # or hide the dash behind a ./ path

This is not a rare edge case; a mistyped redirect or a badly written script can easily create a file whose name begins with a dash, and -- is the clean way to delete it.

6.4 Keeping a Recursive Delete on One Disk: --one-file-system

When you delete a large tree that has other disks mounted inside it, a plain rm -r will happily descend into those mount points and start deleting their contents too. The --one-file-system option tells rm to skip any directory that lives on a different filesystem from where the delete began.

$ rm -rf --one-file-system /mnt/oldroot   # will not wander into other mounts

This is a professional habit when cleaning up an old system root or a chroot that has /proc, /sys, or a data disk mounted underneath it. It draws a firm line around exactly what the delete is allowed to touch.

6.5 The Wildcard and Empty-Variable Traps

Because the shell expands wildcards before rm runs, the greatest danger with rm is not the command itself but what the shell hands it. A stray space turns rm -rf ./tmp into rm -rf . /tmp, which deletes the current directory as well. A wildcard that matches more than you expect deletes all of it at once.

$ rm -rf $DIR/*                    # if $DIR is empty, this becomes rm -rf /*

That last line is a classic scripting disaster. If the variable DIR is unset or empty, the command collapses into rm -rf /* and tries to wipe the system. Defensive scripts quote and check their variables first, for example with [ -n "$DIR" ] before any destructive command, and many use set -u so that an unset variable stops the script instead of expanding to nothing.

Quoting flips the meaning entirely, which is a useful thing to understand. An unquoted rm *.jpg lets the shell expand the star into every matching filename. But rm "*.jpg", with quotes, hides the star from the shell, so rm receives the four characters *.jpg literally and tries to delete a single file whose actual name is *.jpg. This is exactly how you remove a file that was accidentally created with a star in its name, and it is a good reminder that rm never sees your wildcards; the shell does.

The dangerous part of rm is almost never rm itself. It is the shell deciding what * and $VAR turn into before rm ever sees them. Look at what the command will expand to, not just what you typed.

When the target is a symbolic link, rm removes the link itself, not the file it points to. The file at the other end stays exactly where it is; only the small pointer disappears. This is the safe, expected behaviour, and it means you can clean up a broken or unwanted shortcut without any risk to the real data.

$ rm mylink                        # deletes the link; its target is untouched

One detail catches people out when the link points at a directory. A trailing slash changes what you are naming. Without a slash, you name the link; with a slash, you name the directory behind it, and since rm will not remove a directory without -r, it refuses.

$ rm linkdir/
rm: cannot remove 'linkdir/': Is a directory
$ rm linkdir                       # no slash: removes the symlink itself

Shell tab-completion loves to add that trailing slash automatically, so if a delete of a directory symlink fails with "Is a directory", drop the slash and try again.

Back to top

7. Something Most Users Do Not Know

7.1 Removing a Name Is Not Always Deleting the File

Here is the detail that follows straight from the word "unlink". A single piece of data on disk, identified by its inode, can have more than one name pointing at it. These extra names are called hard links, and each one is an equal, first-class name for the same file. Every file keeps a link count: how many names point at its data.

When you run rm, it removes one name and decreases that count by one. The data itself is freed only when the count reaches zero. So if a file has two hard links and you rm one of them, the file is still fully there under its other name.

$ ln important.txt copy2.txt       # a second name for the same data
$ ls -l important.txt              # the "2" is the link count
-rw-r--r-- 2 peter peter 51 Jul  7 10:00 important.txt
$ rm important.txt                 # removes one name; the data survives
$ cat copy2.txt                    # still here, unchanged

This is why "delete" is the wrong mental word and "unlink" is the right one. rm does not destroy a file; it removes a link to it, and the file lives on as long as any link, or any running program, still holds it.

7.2 Deleted Is Not Gone: Recovery and Open Files

Even when the link count hits zero, the bytes are not scrubbed. The system simply marks the disk blocks as free to be reused later. Until something writes over them, the old contents are still physically on the disk, which is why forensic tools can often recover a file deleted minutes ago. The rm --help text says as much: "it might be possible to recover some of its contents, given sufficient expertise and/or time."

There is an even stranger case. If a program still has the file open when you delete it, the name vanishes from the directory but the data stays alive until that program closes the file. The space is not freed, which leads to a classic puzzle: df reports a full disk, yet du cannot find the large files, because they were deleted while a process, often a logging daemon, still held them open.

$ rm huge.log                      # name gone, but rsyslogd still has it open
$ df -h /                          # disk still shows full
$ lsof | grep deleted              # reveals the still-open, already-deleted file

The fix is to restart or signal the program holding the file, at which point the space is finally reclaimed.

If instead you need the data to be truly unrecoverable, rm is the wrong tool. The traditional answer is shred, which overwrites a file's contents before removing it. Be careful here, though: overwriting is far less dependable than it sounds on modern storage. On an SSD the drive's wear-leveling writes each overwrite to different physical cells than the original, and TRIM may already have discarded the old blocks, so the data you meant to scrub can sit untouched elsewhere on the chip. On copy-on-write and journaling filesystems such as Btrfs and ZFS, and on anything with snapshots, RAID, or a virtual disk underneath, the original blocks can likewise survive. For those systems the reliable protection is not overwriting after the fact but encryption from the start, so a deleted file is already unreadable without the key.

An ordinary rm is not a secure wipe: it removes the name and frees the space, but the data stays on the disk until something reuses it. shred can overwrite it first, yet on SSDs and copy-on-write filesystems even that is unreliable, which is why encryption is the protection professionals trust.

7.3 Knowing Where rm Stops

Part of expertise is knowing when a different tool fits better. rm is perfect for deleting a file or a tree you are sure about. Beyond that, others take over.

NeedUseWhy
Make data truly unrecoverable shred, or encryption Overwrites the contents before unlinking, though not reliably on SSDs or copy-on-write disks; plain rm only frees the space
Delete files matching complex rules find ... -delete Selects by age, size, name, or depth, then removes exactly those
Remove only empty directories rmdir Refuses to delete anything that still has contents
Want a trash can with undo trash-cli / gio trash Moves files to a recoverable trash instead of unlinking them

A common surprise is that rm has no built-in "delete everything older than 30 days" mode. That job belongs to find, for example find /var/log -name '*.log' -mtime +30 -delete. Learn rm first anyway: it is on every machine you will ever log in to, including a rescue shell, and understanding unlink versus erase is the foundation the other tools build on.

Back to top

8. Best Practices

  • Read the whole command before pressing Enter. With rm, the path right after -rf is the one that matters. There is no undo and no trash.
  • Prefer rm -I for interactive work. It prompts once before a big or recursive delete without nagging you on every file, catching the runaway wildcard while staying out of the way.
  • Look at what a wildcard expands to first. Run ls *.log before rm *.log, so you delete exactly the list you just saw.
  • Never trust an unquoted variable in a destructive command. An empty $DIR turns rm -rf $DIR/* into a system wipe; quote it, check it is set, and use set -u in scripts.
  • Use --one-file-system when clearing a tree with mounts inside it. It stops a recursive delete from wandering into other disks.
  • Do not treat rm as a secure wipe. It only removes the name and leaves the bytes recoverable. shred can overwrite them, but on SSDs and copy-on-write filesystems it is unreliable, so use encryption when the data is truly sensitive.
  • Reach for the manual without hesitation. The habit that separates beginners from professionals is typing man rm the moment a question comes up.
$ man rm                            # the full manual page
$ rm --help                         # a quick flag summary (GNU)
$ info coreutils 'rm invocation'    # the verbose GNU manual
Back to top

9. Common Mistakes

9.1 Three Common Myths

MythReality
"rm erases the file from the disk." It unlinks a name and frees the space; the bytes stay on disk until reused, and can often be recovered. shred can overwrite them, though not reliably on SSDs or copy-on-write disks, where encryption is the safer answer.
"A deleted file is gone immediately." If a program still has it open, the data lives on until that program closes it, which is why df and du can disagree.
"rm -rf / will wipe my system." Modern GNU rm refuses the literal / by default, but it will still happily delete /home/you or the wrong ./.

9.2 Other Traps to Avoid

  • The stray space. rm -rf . /tmp instead of rm -rf ./tmp deletes the current directory as well. One space changes everything.
  • The empty variable. rm -rf $DIR/* becomes rm -rf /* when $DIR is unset. Always check and quote variables in destructive commands.
  • The over-broad wildcard. rm * in the wrong directory, or rm * .txt with an accidental space, removes far more than intended.
  • Deleting into a mount. A recursive delete crosses into mounted disks unless you add --one-file-system.
  • Assuming rm is secure. Sensitive files are recoverable after a plain rm; use shred when it matters.
  • Filenames that start with a dash. rm -file.txt is read as options and fails. Put -- before the names, or prefix a path such as ./-file.txt.
Back to top

10. Summary

The rm command is short, blunt, and unforgiving, which is exactly what makes it such a clear lesson in how Linux separates a file from its name and its data.

  • rm is short for "remove". It deletes files by unlinking a name, not by erasing the data on the disk.
  • There is no undo and no trash can; a removed file is gone from view instantly, with no confirmation by default.
  • -i asks before every file, -I asks once before a big or recursive delete, -v shows each removal, -f forces and silences errors.
  • -r (also -R, --recursive) deletes a directory and everything inside it; -d and rmdir remove only empty directories.
  • Modern GNU rm refuses rm -rf / by default via --preserve-root, but that guard does not cover the wrong subdirectory.
  • The permission to delete a file lives on the containing directory, not the file: with write access to a folder you can remove a file you do not own, unless the sticky bit (as on /tmp) forbids it.
  • Removing one hard link does not delete the file if other links remain; the data is freed only when the link count reaches zero and no program still holds it open.
  • A deleted file is not erased: its blocks are merely freed and can be recovered until reused. shred can overwrite them, but on SSDs and copy-on-write disks encryption is the reliable protection.
  • The real danger is the shell: wildcards and empty variables can turn a small command into a disaster before rm ever runs.
  • Know where rm stops: shred to truly erase, find -delete for rule-based deletes, rmdir for empty folders, trash-cli for a recoverable trash.
  • When in doubt, type man rm.

This is the quick reference worth keeping:

rm file              remove a single file (no undo, no trash)
rm f1 f2 f3          remove several files
rm *.log             remove every file matching a wildcard
rm -i file           ask before every removal
rm -I *.mp4          ask once before a large or recursive delete
rm -v file           show each file as it is removed
rm -r dir            remove a directory and all its contents
rm -d dir            remove a directory only if it is empty
rm -f file           force: no prompt, no error if missing
rm -rf dir           remove a tree with no questions asked
rm -- -file.txt      remove a file whose name starts with a dash
rm -rf --one-file-system dir   do not cross into mounted disks
shred -u file        overwrite then remove (unreliable on SSDs/CoW)

Small commands like rm hide a surprising amount of how Linux is built, and a single careless delete can undo hours of work with no way back. If your servers matter and you want them maintained by someone who understands what is really happening underneath, that is exactly the kind of work I enjoy helping with.

Back to top
Linux command: rm
Peter Martin
Peter Martin
Joomla Specialist

Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.