How to Remove (Delete) Files and Directories in Linux

The command line is a powerful tool that allows you to perform daily tasks more quickly and efficiently than a graphical interface. But it can also be dangerous if used incorrectly. This is especially true when removing unnecessary files or directories from the system.
Desktop users can use the GUI to easily delete files, and restore those files out of the Trash if needed. However, if you are working on a headless server, the command line utilities allow you to remove multiple files and directories at once using wildcards or other pattern matches.
This article goes through several different tools that allow you to remove files and directories in Linux. We will explain how to use the rm, unlink, shred, and rmdir commands, how to clear out files in bulk with find, and how to delete files in a way you can still undo.
Before You Begin
In Linux, there are several tools that can be used to delete files and directories. Be extra careful when removing files or directories, because once a file is deleted it cannot be easily recovered, even with recovery software.
rm -rf $DIR/ into rm -rf /.Removing a file requires write and execute permission on the directory that holds it, not on the file itself. That is why you can delete a read-only file you do not own as long as you can write to its parent directory, and why owning a file is not enough when the parent directory is closed to you.
File names with a space in them must be escaped with a backslash (\) or wrapped in quotes.
How to Remove Files in Linux
To remove (or delete) a file in Linux from the command line, you can use the rm, shred, or unlink commands.
The unlink
command allows you to remove only a single file, while with rm and shred, you can remove multiple files at once.
Using rm Command
To delete a single file, invoke the rm
command followed by the file name:
rm filenameIf you do not have write permission on the parent directory, the command fails with a “Permission denied” error:
rm: cannot remove 'filename': Permission deniedA different message, “Operation not permitted”, points at a different cause. You will see it when the parent directory has the sticky bit set and you do not own the file, which is what protects other people’s files in /tmp, or when the file carries the immutable attribute.
GNU rm prompts for confirmation when the file is write-protected, standard input is a terminal, and -f was not used, as shown below. The -i option prompts regardless of the file permissions. To remove the file, type y and press Enter.
rm: remove write-protected regular empty file 'filename'?To delete multiple files at once, invoke the rm command followed by the names of the files you want to remove, separated by a space:
rm filename1 filename2 filename3You can also match multiple files with shell glob patterns. For example, to remove all .pdf files in the current directory, you would use the following command:
rm *.pdfThe shell expands the pattern before rm ever runs, so rm receives a finished list of names and has no idea a pattern was involved. When using glob patterns, first list the files with the ls
command so that you can see what files will be deleted before running the rm command:
ls *.pdfUse the rm with the -i option to confirm each file before deleting it:
rm -i filename1 filename2To remove files without prompting, even if the files are write-protected, pass the -f (force) option to the rm command:
rm -f filename1 filename2You can also combine rm options. For example, to remove all .txt files in the current directory without a prompt in verbose mode, use the following command:
rm -fv *.txtremoved 'notes.txt'
removed 'report.txt'Each line confirms one deletion, which gives you a record of what the glob actually matched after the fact.
Using shred Command
When a file is removed in Linux, the actual data is not deleted; only the reference inode (metadata about a file) is removed, and the corresponding data blocks are marked as available for reuse. The content of the file will stay on the disk until the space is needed for new data.
The shred command overwrites a file to hide its contents, making it more difficult to recover the deleted file.
To overwrite and delete a file with shred, invoke the command with the -u option followed by the file name:
shred -u filenameBy default shred writes three passes of random data over the file, then truncates and removes it. Adding the -z option writes a final pass of zeros, so the file does not obviously look like it was shredded:
shred -uz filenameYou can also pass multiple files separated by a space:
shred -u filename1 filename2 filename3Before you rely on shred, understand what it assumes. The GNU documentation is direct about it: shred depends on the filesystem and the hardware overwriting data in place, and a lot of modern storage does not. The overwrite may leave the original blocks intact on ext3 and ext4 filesystems mounted in data=journal mode, copy-on-write or snapshotting filesystems such as Btrfs and ZFS, RAID arrays, compressed filesystems, and SSDs, where wear leveling scatters writes across physical blocks that the operating system cannot address directly. Backups and mirrors are outside its reach entirely.
On ext3 and ext4 filesystems using the default data=ordered mode or data=writeback, shred -u can be effective when the underlying device overwrites blocks in place. That generally means a conventional magnetic disk with no snapshots, mirrors, or backups. When the requirement is that nothing is recoverable from the device, full-disk encryption from the start, or the drive’s own secure erase command, is the approach that actually holds.
Using unlink Command
To remove a file with unlink, invoke the command followed by the name of the file you want to remove:
unlink filenameOn success, the command does not produce any output and returns zero. unlink accepts exactly one file operand and cannot remove directories. Like rm, it does not interpret glob patterns itself. The shell still expands an unquoted pattern before starting the command, so unlink *.log deletes the file if exactly one name matches and fails if several names match. Do not use unlink as a guard against unexpected shell expansion.
Removing Files in Bulk with find
rm works on the names you hand it, which is fine until the files you want are scattered across a tree or defined by something other than their name. find
selects files by pattern, age, size, or type, and then deletes what it matched.
Always run the search on its own first. With no action attached, find only prints the matches, and that preview is the cheapest way to catch an expression that is wider than you intended:
find /var/log/app -type f -name '*.log'Once the list looks right, add -delete as the final action:
find /var/log/app -type f -name '*.log' -deleteHere is a breakdown of the command above:
/var/log/app- The directory to search, including everything below it.-type f- Restricts the matches to regular files, so directories are left alone.-name '*.log'- Matches only names ending in.log. The quotes keep the shell from expanding the pattern, sofindreceives it intact.-delete- Removes each matched file.
Deleting by age is the other common cleanup. The -mtime test counts completed 24-hour periods since the file was last modified. Because find rounds the age down before comparing it, +30 starts matching after 31 full 24-hour periods:
find /backups -type f -mtime +30 -deleteFor finer control, -mmin counts completed minutes instead, so -mmin +90 starts matching after 91 full minutes.
You can also delete by size. This removes every file larger than 1 GB under /var/tmp:
find /var/tmp -type f -size +1G -delete-delete is not part of the POSIX specification, so some non-GNU implementations do not have it, and it will not remove a directory unless that directory is already empty. Where it is missing or not enough, -exec calls rm on the matches instead:
find /var/log/app -type f -name '*.log' -exec rm {} +The trailing + collects the matched files and passes them to rm in batches rather than starting a new process for every file, which is noticeably faster on large trees. Replacing + with \; runs one rm per file, which you need only when the command must handle the files one at a time.
-delete at the end of the expression. find reads its tests in order, so find . -delete -name '*.log' deletes everything it walks into before the name test is ever applied.Safer Removal Options
rm -i prompts for every single file, which is thorough and quickly becomes tedious on anything larger than a handful. The -I option is the middle ground: it asks once, and only when you are removing more than three files or deleting recursively.
rm -I *.logrm: remove 12 arguments?One prompt tells you how many files the glob expanded to, which is exactly the number you want to see before a wildcard deletion. The same behavior is available as --interactive=once, alongside --interactive=always for the -i behavior and --interactive=never to suppress prompts.
When you clear a tree that might contain a mount point, add --one-file-system. During recursive removal, rm then skips any directory that sits on a different filesystem than the path you passed, which keeps a stray deletion from walking into a mounted backup drive or a network share:
rm -rf --one-file-system /mnt/stagingGNU rm refuses to operate on / recursively, which is the --preserve-root behavior applied by default. That guard is narrower than it sounds: it protects the literal path /, not rm -rf /*, where the shell expands the glob into a list of top-level directories and rm never sees a root argument at all.
How to Remove Directories (Folders)
In Linux, you can remove/delete directories
with the rmdir and rm commands.
rmdir is a command-line utility for deleting empty directories, while with rm, you can remove directories and their contents recursively.
Using rmdir Command
rmdir deletes a directory only when it is already empty, and refuses otherwise. That refusal is the feature: it lets you clear a directory you believe is empty without first checking its contents, and the command stops you if you were wrong.
To remove an empty directory, use the rmdir command with the directory name as argument:
rmdir dirnameIf the directory is not empty, you will get an error message:
rmdir: failed to remove 'dirname': Directory not emptyTo remove a directory along with its empty parents, add the -p option:
rmdir -p parent/child/grandchildUsing rm to Remove Directories
By default, when used without any option, rm cannot remove directories.
To remove an empty directory with rm, invoke the command with the -d option:
rm -d dirnameTo remove non-empty directories and all the files within them, use the rm command with the -r (recursive) option:
rm -r dirnameIf a directory or a file within the directory is write-protected, you will be prompted to confirm the deletion.
To remove non-empty directories and all files without being prompted, use rm with the -r (recursive) and -f options:
rm -rf dirnameTo remove multiple directories at once, use rm -r followed by the directory names separated by a space:
rm -r dirname1 dirname2 dirname3As with files, you can also use glob patterns to match multiple directories.
A symbolic link that points to a directory is a common source of confusion here. Remove the link itself with rm link, and leave the trailing slash off. Writing rm -r link/ follows the link and deletes the contents of the directory it points to. Our guide on removing symbolic links
covers the details.
Sending Files to the Trash Instead
Nothing above is reversible. If what you actually want is the desktop behavior, where a deleted file sits in the Trash until you empty it, the command line can do that too.
On a system with a desktop environment installed, gio is usually already present as part of GLib:
gio trash filenameThe file moves to ~/.local/share/Trash, where your file manager will show it and where gio trash --restore can bring it back. Run gio trash --empty to clear it out for good.
trash-cli is the option that does not assume a desktop, and it works the same way on a server. Install it on Ubuntu, Debian, and Derivatives:
sudo apt install trash-cliOn Fedora, RHEL, and Derivatives:
sudo dnf install trash-cliThe package provides trash-put to delete, trash-list to see what is in there, and trash-restore to pick a file back out:
trash-put filenameBoth tools move the file rather than copying it, so they only work within a single filesystem. A file on a separate mount goes to a trash directory on that mount, and neither tool can trash a file on a read-only filesystem.
Quick Reference
For a printable quick reference, see the rm cheatsheet .
| Command | Description |
|---|---|
rm filename | Delete a single file |
rm filename1 filename2 | Delete multiple files |
rm *.pdf | Delete all .pdf files in the current directory |
rm -i filename | Prompt before each deletion |
rm -I *.log | Prompt once when more than three files match |
rm -f filename | Force delete without prompting |
rm -v filename | Print each file as it is removed |
rm -r dirname | Recursively delete a directory and its contents |
rm -rf dirname | Force recursive delete without prompting |
rm -rf --one-file-system dir | Recursive delete that will not cross mount points |
rm -- -filename | Delete a file whose name starts with a dash |
rmdir dirname | Delete an empty directory |
rmdir -p a/b/c | Delete a directory and its empty parents |
unlink filename | Delete a single file via the unlink system call |
shred -uz filename | Overwrite, zero, and delete a file |
find dir -type f -name '*.log' -delete | Delete matching files anywhere below dir |
find dir -type f -mtime +30 -delete | Delete files at least 31 days old |
gio trash filename | Move a file to the Trash instead of deleting it |
Troubleshooting
“Permission denied”
You do not have write and execute permission on the directory that holds the file. Permissions on the file itself do not matter here. Check the parent directory with ls -ld dirname, adjust it with chmod
if you own it, or prefix the command with sudo if you need elevated privileges.
“Operation not permitted”
Different cause than the message above. Either the parent directory has the sticky bit set and the file belongs to someone else, or the file is immutable. Check with lsattr filename, and clear the attribute with sudo chattr -i filename if an i appears in the output.
“Directory not empty” when using rmdirrmdir only removes empty directories. To delete a directory and everything inside it, use rm -r dirname.
“Is a directory” when deleting with a globrm dirname/* matches subdirectories along with files, and rm skips them with this error unless you add -r. Use rm -r dirname/* to include them, or find dirname -maxdepth 1 -type f -delete to remove only the files.
Accidentally deleted files with a wildcard
Files deleted with rm are not sent to the Trash and cannot be recovered easily. Before running rm *.ext, preview the matches with ls *.ext first. For critical operations, use rm -I to confirm the expanded count, or delete through trash-put so the files remain recoverable.
File with a name starting with a dash cannot be deleted
If a filename begins with a dash, rm interprets it as an option. Use rm -- -filename or rm ./-filename to work around this.
“Argument list too long”
The glob expanded to more files than the shell can pass in one command. Use find . -maxdepth 1 -type f -name '*.log' -delete instead, so the shell never builds one large argument list. The -delete action removes each match directly, while -exec rm {} + batches the matches when you need to call rm.
FAQ
What is the difference between rm and unlink?
Both remove files. rm accepts one or more file operands and supports options for recursion, prompting, and forced removal. unlink accepts exactly one file operand and has no removal options. Neither command expands glob patterns; the shell expands them before the command runs.
Can I recover a file deleted with rm?
Not easily. rm does not move files to a Trash folder; it removes the directory entry and marks the disk blocks as free. Recovery may be possible with forensic tools if the blocks have not been overwritten, but it is not guaranteed. Stop writing to the filesystem immediately if you intend to try.
How do I delete files older than 30 days?
Use find with the -mtime test: find /path -type f -mtime +30 -delete. Because find rounds file ages down, this starts matching after 31 full days. Use -mtime +29 if you want files to match as soon as they reach 30 full days, and always run the command once without -delete to review the list.
When should I use shred instead of rm?
Use shred -u only when the filesystem and storage device overwrite data in place. It can be effective with ext3 or ext4 in data=ordered or data=writeback mode on a conventional magnetic disk. Do not rely on it with SSDs, filesystems that journal file data or use copy-on-write, RAID, snapshots, or backups. For a whole device, rely on encryption or the drive’s secure erase instead.
Is rm -rf dangerous?
Yes. rm -rf deletes everything in the target path immediately and without confirmation. Never run it with /, ~, or a variable that might be empty as the argument. Adding -I restores a single confirmation prompt without giving up the recursion.
How do I delete all files in a directory without deleting the directory itself?
Use rm -r dirname/* to delete the contents while keeping the directory. Note that * does not match hidden files, so entries beginning with a dot survive. To include them, use find dirname -mindepth 1 -delete.
Conclusion
The rm command is the primary tool for deleting files and directories in Linux. Use rmdir when you want to safely remove only empty directories, unlink when removing a single file, find when the files are chosen by age or pattern rather than by name, and shred when the contents matter more than the file. When you are working somewhere a mistake would be expensive, rm -I costs one keystroke and tells you how many files you are about to lose. For a complete reference on rm options and flags, see the rm command guide
.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page