rm — Delete Files and Directories
Practical guide to rm: delete files and directories, prompt safely with -i/-I, remove recursively with -rf, and avoid disasters like rm -rf /.
rm (remove) deletes files and directories from the filesystem – and it does so for good: unlike moving things to a trash bin, nothing is kept around, and deleted data cannot be recovered without a backup. Day to day you reach for rm to clear out temporary files, stale logs or entire project folders. Precisely because it is irreversible, it pays to know the safe variants: rm -i asks before each file, while rm -I warns once before large or recursive deletions. Take special care with rm -rf next to variables or glob patterns – an empty $VAR or a stray /* can wipe out whole systems.
Basic Removal
rm <file> — Remove a single file.
rm temp.txtrm <file1> <file2> <file3> — Remove multiple files at once.
rm old.log debug.log error.logrm *.tmp — Remove all files matching a glob pattern.
rm *.tmprm -v <file> — Verbose mode. Print each file as it is removed.
rm -v *.logInteractive & Safe Removal
rm -i <file> — Interactive mode. Prompt for confirmation before each file.
rm -i important-data.*rm -I <files> — Prompt once before removing more than 3 files or when removing recursively.
rm -I *.logrm --interactive=once <files> — Same as -I. Prompt once for bulk removals.
rm --interactive=once /tmp/session_*rm -f <file> — Force removal. Never prompt and ignore nonexistent files.
rm -f lockfile.pidDirectory Removal
rm -r <directory> — Remove a directory and all its contents recursively.
rm -r ./old-project/rm -rf <directory> — Force remove a directory recursively without prompts. Use with extreme caution.
rm -rf ./build/rm -ri <directory> — Remove a directory recursively with confirmation for each file.
rm -ri ./unknown-folder/rm -d <directory> — Remove an empty directory. Fails if the directory is not empty.
rm -d ./empty-dir/rmdir <directory> — Remove an empty directory (dedicated command, same as rm -d).
rmdir ./empty-dir/rmdir -p <path/to/nested/dir> — Remove a directory and its empty parent directories.
rmdir -p ./a/b/c/Safety Options
rm --preserve-root — Refuse to operate recursively on /. This is the default behavior.
rm -rf --preserve-root /some/path/rm --preserve-root=all — Additionally reject any argument that is a mount point.
rm -rf --preserve-root=all /mnt/data/rm --one-file-system -r <directory> — Skip directories on different filesystems during recursive removal.
rm -rf --one-file-system /var/tmp/Special Cases
rm -- <file> — Remove a file whose name starts with a dash. The -- signals end of options.
rm -- -strange-filename.txtrm ./-<file> — Alternative: remove a dash-prefixed file by prepending ./
rm ./-strange-filename.txtrm -f <file_with_special_chars> — Force remove files with special characters in the name.
rm -f 'file with spaces.txt'find <dir> -inum <inode> -delete — Remove a file by its inode number. Last resort for unremovable filenames.
ls -i; find . -inum 1234567 -deleteFind & Remove Patterns
find <dir> -name '<pattern>' -delete — Find and delete files by name pattern. Faster than -exec rm.
find . -name '*.tmp' -deletefind <dir> -name '<pattern>' -type f -delete — Delete only files (not directories) matching a pattern.
find . -name '.DS_Store' -type f -deletefind <dir> -empty -type d -delete — Delete all empty directories within a tree.
find ./project/ -empty -type d -deletefind <dir> -mtime +<days> -delete — Delete files older than N days.
find /var/log/ -name '*.log' -mtime +90 -deletefind <dir> -size +<size> -delete — Delete files larger than a given size.
find /tmp/ -size +100M -deletefind <dir> -name '<pattern>' -print -delete — Print each file before deleting it (verification output).
find . -name '*.bak' -print -deletefind <dir> -name '<pattern>' -print0 | xargs -0 rm -v — Find and remove files safely with verbose output. Handles spaces in filenames.
find . -name '*.cache' -print0 | xargs -0 rm -vSafer Alternatives
mv <file> /tmp/ — Move to /tmp instead of deleting. Files are cleaned on reboot.
mv suspicious-file.dat /tmp/trash-put <file> — Move file to trash (trash-cli package). Can be recovered later.
trash-put document.pdftrash-list — List all files in the trash (trash-cli).
trash-listtrash-restore — Interactively restore a file from the trash (trash-cli).
trash-restoretrash-empty — Permanently empty the trash (trash-cli).
trash-emptyalias rm='rm -I' — Shell alias to always prompt before bulk deletions.
alias rm='rm -I'Dangerous Commands to Avoid
rm -rf / — NEVER RUN. Attempts to delete the entire filesystem. Blocked by --preserve-root default.
# DO NOT RUN — destroys your entire systemrm -rf /* — NEVER RUN. Bypasses --preserve-root by expanding /* to individual paths. Destroys everything.
# DO NOT RUN — the glob expansion bypasses root protectionrm -rf $VARIABLE/ — DANGEROUS if variable is empty or unset. Expands to rm -rf / which deletes everything.
# ALWAYS quote and check: rm -rf "${DIR:?Variable not set}/"rm -rf "${DIR:?}"/* — Safe pattern. The :? causes the shell to abort with an error if DIR is empty or unset.
DIR=/var/cache/app; rm -rf "${DIR:?Variable not set}"/* Conclusion
rm is powerful and final: there is no trash bin, and once data is gone it is gone unless you have a backup. For everyday use, rm <file>, rm -r <directory> and the find … -delete patterns cover most needs. Stay aware of the dangerous cases: rm -rf with an empty variable, a stray space before /, or a /* can erase an entire system. Two simple habits protect you – quote and guard variables with "${DIR:?}", and set an alias rm='rm -I' so the shell prompts before bulk deletions. When you need recoverability, use trash-cli instead of rm.
Further Reading
- GNU Coreutils: rm – the official reference for every option
- rm(1) manual page – the Linux man page with concise option descriptions