rm deletes files and directories on Linux, and it does it permanently.
Let me walk you through all the options available for safe deletion, with a terminal example for each one.
What rm removes when you run it
A file name is a directory entry, and that entry points at an inode which holds the metadata and the addresses of the data blocks.
rm removes the entry and drops the inode link count by one. The data stays readable while a second name points at the same inode, and the kernel releases the blocks when that count reaches zero.
The mechanism shows up in the terminal, so I created a hard link, removed the first name, and read the file back through the second one.

The command reported the one name it removed and said nothing else. Reading backup.txt still returned the line I had written into report.txt, which is the link count behaving as documented.
An open file handle behaves the same way, and a process that holds the file open keeps reading and writing after rm returns. The kernel releases that space when the process closes it.
Nothing in this path moves the file anywhere you can restore it from, because rm is the unlink call. The command returns with nothing to show you and nothing to undo.
Before you delete anything
The filesystem checks two permissions before a name disappears, write access to the file and write access to the directory.
The second one catches people out, because unlink only needs write permission on the directory. A read-only file sitting inside a directory you own is removable.
I tested that with a chmod 444 file. A read-only file inside a directory I owned came out with rm and no prompt at all, which says the prompt is not a permission check. The permission bits themselves are covered in the chmod command guide.
When standard input is a terminal, the file is unwritable, and force is absent, rm asks about that file. The same command inside a script stays silent because nothing is attached to ask.
| Option | What it changes |
|---|---|
| -f, –force | removes without prompting and ignores names that do not exist |
| -i | prompts before every file |
| -I | one prompt when more than three names arrive or the removal is recursive |
| –interactive=WHEN | never, once, or always |
| -r, -R, –recursive | removes directories and their contents |
| -d, –dir | removes empty directories |
| -v, –verbose | prints each name as it is removed |
| –one-file-system | skips directories on a different filesystem |
| –preserve-root | refuses to recurse into /, on by default |
| –no-preserve-root | allows that removal |
Running rm –version prints either GNU coreutils or the Rust rewrite that Ubuntu 26.10 ships as its default rm, and both aim at the same option set. Check which one answers before you lean on the guards in the table.
Read the path back before the command, not after. That step is the answer the Server Fault thread on accidental rm -rf reaches for, and it costs one second.
Removing files with rm
Which option you need depends on what you are unsure about, the names the command will receive or your own typing.
| How much do you want to be asked | Option | What happens |
|---|---|---|
| nothing | rm file | the file goes as soon as the command returns |
| once, for a large or recursive command | -I | one question covers the whole argument list |
| before every file | -i | each name gets its own question |
| nothing, even for a protected file | -f | no question, and a missing name stops being an error |
Removing one file or several
rm notes.txt
rm notes.txt draft.txt
Names are separated by spaces, and the command reports nothing at all when it succeeds.

Verbose output turns that silence into a receipt, which is the version I use whenever a directory holds something I might want back.
Reading the glob before the shell expands it
rm -v *.pdf
The shell expands the asterisk into a list of names before rm starts, so the command never sees the wildcard itself.

Print the expansion first when the directory matters, since echo *.pdf shows the argument list that the command will receive. Reading the directory with ls is the same check by eye.
Asking before each file
rm -i *.pdf

An answer that is not affirmative skips that file and leaves the rest of the command alone, so a partial answer is a partial delete rather than a failure. An alias can also add -i to every rm you type, and the alias guide shows where to check for one.
Answers can be piped into the prompt because it reads standard input, so a scripted yes and no deletes one file and keeps the next.
Asking once instead
rm -I *.log

GNU rm raises that single question in two cases, with more than three file arguments or with a recursive removal. A short list passes straight through, and the name after that brings the question back.
Removing a write-protected file

Force answers the question in advance and also drops the error for a name that does not exist, which is why it appears in cleanup scripts.
rm -f important.pdf
Names that start with a dash
A leading dash makes rm read the name as an option of its own, and the double dash ends option parsing for the rest of the line.
rm -- -notes.txt
Removing directories with rm
Which option to reach for depends on whether the directory is empty and on whether something is mounted inside it.
Empty directories
rm -dv empty1 empty2
That removes empty directories and refuses anything with contents, which is the same boundary rmdir draws. The directory removal guide covers the other routes to the same result, and find and delete empty directories clears a tree of them in one pass.
Recursive removal
rm -rv project

Entries are reported as the walk returns, so the files appear before the directory that held them. Recursion is also where a wrong path hurts, since the walk follows everything under the directory you named.
Keeping the walk on one filesystem
rm -rf --one-file-system data

I mounted a tmpfs inside the data directory and ran that command against it, which left the mount untouched and the exit status at 1. The output named the directory rm skipped.
Without the option the same walk reaches into the mount, and the kernel answers with Device or resource busy while something holds it open.
When rm stops or fails
These are the failures that stop a delete partway.
| Message | Cause | What to run |
|---|---|---|
| Permission denied | your user cannot write to the directory that holds the name | check the directory with ls -l, then fix ownership or run the command with sudo |
| Directory not empty | -d was used on a directory that still holds something | rm -r for the directory and its contents |
| Argument list too long | the shell expanded a glob past the kernel argument limit | find with -delete, or split the list through xargs |
| it is dangerous to operate recursively on ‘/’ | the preserve-root failsafe fired | confirm the path, then decide whether the root removal is what you meant |
| Read-only file system | the filesystem is mounted read-only | remount it read-write or edit the mount options |
| Operation not permitted | the file carries the immutable attribute | confirm with lsattr, then clear it with chattr -i |
The root failsafe is the oldest of the five, and it fires before rm opens anything. GNU rm refuses to recurse into the root directory unless –no-preserve-root is passed, which is why the command from the old danger lists no longer behaves the way those write-ups describe.


A directory with contents is a boundary rather than a fault, and the message says which boundary you hit.
The argument list is the failure that surprises anyone working in a directory with a large number of files. The shell builds one argument vector, and the kernel rejects that vector once it passes the ARG_MAX limit, which is derived from the stack limit of the process.

I reproduced it with 30,000 empty files and a lowered stack limit, the setting the kernel reads when it computes the limit. The same directory empties through find, which walks the tree instead of handing every name to one process, and the find command guide covers the walk itself.
find cache -name '*.tmp' -print -delete

Permission denied and a read-only filesystem both come from the kernel rather than from rm, so the repair is ownership or the mount, not another flag. The permission denied walkthrough takes the ownership route from the error message.
Recovering a file rm already removed
What you can get back depends on what happened to the inode, so check before you reach for a recovery tool.
- Check whether a process still holds the file open, since the kernel keeps the data alive for as long as it does.
- Copy the file out of /proc/<pid>/fd/ while that handle exists, which is the one route that needs no recovery tool at all.
- Stop writing to that filesystem, because every new write can claim the blocks the deleted file used.
- Restore from the newest backup or snapshot before reaching for an undelete utility.
- Work on an image of the filesystem when the data matters enough to spend the time.
The GNU manual says plainly that the contents of a removed file are usually recoverable, and that shred exists for the cases where they must not be. A guide on this site walks the longer version of that story, after a system directory went missing and a rebuild turned out to be faster than any recovery.
Send it to the trash instead
A delete that can be undone only needs the directory entry moved, and trash-cli does that from the terminal.
trash-put report.pdf
trash-list
trash-restore

The file leaves the working directory and the trash keeps the path it came from, so putting it back is one command rather than a filesystem recovery job.
Desktop sessions already ship gio trash, which moves the entry into the same trash directory the file manager uses. The extra step costs one command and it turns a wrong glob into a single trash-restore.
Frequently asked questions
Does rm delete the data or just the name?
rm removes the directory entry and drops the inode link count. The data stays readable while a second name points at that inode or a process holds the file open, and the kernel releases the blocks when the count reaches zero.
Why does rm ask for confirmation on one machine and not another?
It asks when standard input is a terminal, the file is unwritable, and force is absent. A script or a pipe has no terminal on standard input, so the same file is removed without a question.
How do I delete a directory that is not empty?
Use rm -r for the directory and its contents. When the argument list is too long for one command, find with -delete walks the tree instead.
Can I recover a file deleted with rm?
Often, when the blocks have not been reused. Check whether a process still holds the file open, stop writing to that filesystem, and try a backup or snapshot before any recovery tool.
Is rm -rf / still dangerous?
GNU rm refuses to recurse into the root directory unless –no-preserve-root is given. The command in the old warnings is the expanded form rm -rf /*, and the failsafe protects the exact root path rather than a mistyped variable.
