rmRemove files and directories
rm deletes names from directories; with -r it deletes whole trees. There is no trash can and no undo. It also explains a classic incident: you delete a huge log, but the disk stays full because a process still has the file open.
rm [OPTION]... FILE...You are cleaning up a copy of the source tree you made for testing.
rmRemove directory entries. When the last name and the last open handle are gone, the space is freed.
rm doesn't erase data. For each argument it calls unlinkat(), which removes one name from its directory and decrements the inode's link count. With -r it walks the tree depth-first (using fts), unlinking files and then removing each emptied directory with unlinkat(AT_REMOVEDIR). The kernel frees the inode and its data blocks only when two counts reach zero: the link count (names pointing to it) and the number of open file descriptors. So if a process still has a log open, rm makes the name disappear but df shows no space freed; lsof +L1 lists such deleted-but-open files. Permission to delete depends on the directory, not the file: you need write and execute on the directory. On a write-protected file rm asks first unless -f is given, and in sticky directories like /tmp you can only delete files you own. rm refuses / unless you pass --no-preserve-root.
rm removes a name; the kernel frees the data only when no names and no open file descriptors are left.
The node app opened /var/log/app/app.log at startup and writes through file descriptor 21. The inode has one name and one open descriptor.
-r, -RRecursive: remove directories and their contents-fForce: no prompts, no error for missing files-iPrompt before every removal-IPrompt once if removing more than 3 files or recursing-vPrint each removed file and directory-dRemove empty directories (like rmdir)--End of options: allows names starting with ---one-file-systemWith -r, skip directories on other mounted filesystems--preserve-rootDefault: refuse to operate recursively on /rm -rf $DIR/* in a scriptIf DIR is empty or misspelled this becomes rm -rf /*. Unquoted, a path with spaces also splits into several targets.
rm -rf -- "${DIR:?}"/* and set -euo pipefail at the top of scriptsDeleting a huge log of a running service to free disk spaceThe process keeps the inode open, so no space is freed until it closes the file.
Truncate instead: sudo truncate -s 0 /var/log/app/app.log (or : > file), then fix rotationsudo rm -rf /usr /local/old-app (meant /usr/local/old-app)One stray space turns one path into two, and /usr goes first. The --preserve-root failsafe only protects / itself.
ls the exact path first, then recall the line and swap ls for rm; rm -rI asks once before a big recursive deleterm *.log -f in a directory where a file named -rf existsGlobs can produce names starting with -, which rm then reads as options.
rm -- *.log or rm ./*.logTry these on a Linux machine of your own. Each task has a hint and a solution.
Create ~/tmp-test with two files inside, then delete the whole directory, printing each removal.
Create a file literally named --help in your home, then delete it.
Prove that rm doesn't free space while a file is open: open a big file with a background process, delete it, and find it with lsof.
rmRemove files and directories
rm deletes names from directories; with -r it deletes whole trees. There is no trash can and no undo. It also explains a classic incident: you delete a huge log, but the disk stays full because a process still has the file open.
rm [OPTION]... FILE...You are cleaning up a copy of the source tree you made for testing.
rmRemove directory entries. When the last name and the last open handle are gone, the space is freed.
rm doesn't erase data. For each argument it calls unlinkat(), which removes one name from its directory and decrements the inode's link count. With -r it walks the tree depth-first (using fts), unlinking files and then removing each emptied directory with unlinkat(AT_REMOVEDIR). The kernel frees the inode and its data blocks only when two counts reach zero: the link count (names pointing to it) and the number of open file descriptors. So if a process still has a log open, rm makes the name disappear but df shows no space freed; lsof +L1 lists such deleted-but-open files. Permission to delete depends on the directory, not the file: you need write and execute on the directory. On a write-protected file rm asks first unless -f is given, and in sticky directories like /tmp you can only delete files you own. rm refuses / unless you pass --no-preserve-root.
rm removes a name; the kernel frees the data only when no names and no open file descriptors are left.
The node app opened /var/log/app/app.log at startup and writes through file descriptor 21. The inode has one name and one open descriptor.
-r, -RRecursive: remove directories and their contents-fForce: no prompts, no error for missing files-iPrompt before every removal-IPrompt once if removing more than 3 files or recursing-vPrint each removed file and directory-dRemove empty directories (like rmdir)--End of options: allows names starting with ---one-file-systemWith -r, skip directories on other mounted filesystems--preserve-rootDefault: refuse to operate recursively on /rm -rf $DIR/* in a scriptIf DIR is empty or misspelled this becomes rm -rf /*. Unquoted, a path with spaces also splits into several targets.
rm -rf -- "${DIR:?}"/* and set -euo pipefail at the top of scriptsDeleting a huge log of a running service to free disk spaceThe process keeps the inode open, so no space is freed until it closes the file.
Truncate instead: sudo truncate -s 0 /var/log/app/app.log (or : > file), then fix rotationsudo rm -rf /usr /local/old-app (meant /usr/local/old-app)One stray space turns one path into two, and /usr goes first. The --preserve-root failsafe only protects / itself.
ls the exact path first, then recall the line and swap ls for rm; rm -rI asks once before a big recursive deleterm *.log -f in a directory where a file named -rf existsGlobs can produce names starting with -, which rm then reads as options.
rm -- *.log or rm ./*.logTry these on a Linux machine of your own. Each task has a hint and a solution.
Create ~/tmp-test with two files inside, then delete the whole directory, printing each removal.
Create a file literally named --help in your home, then delete it.
Prove that rm doesn't free space while a file is open: open a big file with a background process, delete it, and find it with lsof.