rm removes files and directories. There’s no recycle bin on a server. What rm deletes is gone, unless you have a backup. A few habits make it much safer.

rm [options] FILE...

Delete files

rm notes.txt
rm a.log b.log c.log
rm *.tmp

If a file is write-protected, rm asks for confirmation. -f (force) skips that prompt. It also stays silent about files that don’t exist.

Delete directories

rmdir empty-dir              # only works on empty directories
rm -r old-project            # a directory and everything in it
rm -rf old-project           # the same, without any prompts

-r (recursive) is needed for directories. rm -rf is the command behind most “I deleted the wrong thing” stories, so treat it with care.

Safe habits

1. Look before you delete. Run ls with the same arguments first:

ls /var/www/old-site/cache/*
rm -r /var/www/old-site/cache/*

2. Use -i or -I for interactive work.

rm -i *.log      # ask about each file
rm -I *.log      # ask once if deleting more than 3 files or recursively

3. Prefer absolute paths, and never use unchecked variables.

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

Guard variables in scripts:

rm -rf "${BUILD_DIR:?BUILD_DIR is not set}/"*

${VAR:?} aborts the script if the variable is empty or unset. Also use set -u in Bash scripts. See Bash scripting basics.

4. cd and then delete is fragile. Write cd /some/dir && rm -rf ./*, never cd /some/dir; rm -rf *. With ;, a failed cd means the deletion runs in whatever directory you’re in.

5. GNU rm refuses rm -rf / by default (--preserve-root). It does not protect you from rm -rf /* or rm -rf /var.

6. Move instead of delete when you’re unsure:

mkdir -p ~/trash && mv old-config ~/trash/

Files with awkward names

rm -- -file-starting-with-dash
rm ./-file-starting-with-dash
rm "file with spaces.txt"
rm -i -- *                      # pick interactively

For names with unprintable characters, delete by inode number:

ls -li                                   # find the inode number
find . -maxdepth 1 -inum 1234567 -delete

“Argument list too long”

rm *.jpg fails when the glob expands to hundreds of thousands of files. Use find:

find /path -maxdepth 1 -name '*.jpg' -delete

Delete by age, which is useful for old backups and logs:

find /var/backups/app -type f -name '*.sql.gz' -mtime +14 -print     # check first
find /var/backups/app -type f -name '*.sql.gz' -mtime +14 -delete

See find command examples.

“Operation not permitted” or “Permission denied”

  • You need write permission on the directory that contains the file, not on the file itself.
  • As root, a file with the immutable attribute still can’t be deleted. Check with lsattr file and remove the attribute with sudo chattr -i file.
  • Files inside a container’s volume may be owned by another UID. Use sudo.
  • “Device or resource busy” means the path is a mount point. Unmount it first.

Deleted, but disk space isn’t freed

If a running process still has a deleted file open (a large log, for example), the space stays in use until the process closes it:

sudo lsof +L1            # deleted-but-open files

Restart or reload that service, or truncate the file through /proc. To empty a live log without deleting it, truncate it instead:

sudo truncate -s 0 /var/log/app/big.log

See disk full troubleshooting and lsof.

Secure deletion

shred -u file overwrites a file before deleting it. On SSDs and journaling or copy-on-write filesystems, overwriting isn’t reliable. For sensitive data, use encryption at rest and delete the keys instead.

Recovering deleted files

There’s no undo. On ext4 you can sometimes recover files with tools like extundelete or testdisk if you stop writing to the disk immediately. Don’t count on it. Backups are the real protection. See automated backups.

Quick reference

Task Command
Delete file rm file
Delete empty dir rmdir dir
Delete dir and contents rm -r dir
No prompts rm -rf dir
Confirm each rm -i
Confirm once rm -I
Delete many by pattern find . -name '*.tmp' -delete
Empty a live log truncate -s 0 file

Related: cp and mv.

  • Linux
  • Command Line
  • Basics