rm
rm(remove)用于删除文件和目录。没有回收站,删掉就是删掉了,所以这条命令的重点不在选项,而在怎么不删错。
rm [选项] 文件...默认只删文件,删目录要加
-r默认不会问,删成功也没有任何输出
rm 调的是 unlink,删掉的是目录项,也就是那个文件名,同时把 inode 的链接数减一。只有链接数降到 0、并且没有任何进程还打开着这个文件时,数据块才会被回收。
由此有三个实际后果:
- 文件有硬链接时,删掉一个名字内容还在,剩下的名字照样能读,见 ln
- 删掉一个正被进程打开的文件,磁盘空间不会立刻回来,要等进程退出;
lsof +L1能查出这类文件 - 数据块只是被标记为可用,并没有擦除,所以恢复理论上可能 —— 但只要还在写盘就随时会被覆盖,别指望
| 选项 | 说明 |
|---|---|
-r |
递归删除目录及其内容(recursive),-R 等价 |
-f |
强制(force),文件不存在也不报错,不做任何提示 |
-i |
每个文件都问一次(interactive) |
-I |
删三个以上文件、或带 -r 时,统一问一次 |
-d |
删除空目录(directory),相当于 rmdir |
-v |
打印每一个被删掉的文件(verbose) |
--one-file-system |
递归时不越过文件系统边界,配合 -rf 能挡住一类事故 |
--preserve-root |
拒绝对 / 动手,默认就是开的 |
1. 删文件和目录
rm a.txtrm -r dir/rm -rf dir/ # 目录不存在也静默返回成功2. -I 比 -i 更有用
rm -I *.log
-i是每个文件问一次,几十个文件时只会让人一路按 y,防护等于不存在-I只在数量超过三个或递归删除时问一次,这一次才会真的看一眼
3. 变量为空是最常见的事故
rm -rf $dir/build # $dir 为空时展开成 rm -rf /buildrm -rf "${dir:?未设置}" # 变量为空直接报错退出,不执行路径变量一律加引号,
:?让空值变成一次失败而不是一次删除 引号也管空格:rm -rf "/var/log /tmp"是一个不存在的路径,而不是两个目标
4. 文件名以 - 开头
rm -- -weird.txtrm ./-weird.txt
-开头会被当成选项,用--结束选项解析,或者给个./前缀
5. 按条件批量删
find . -name '*.tmp' -print # 先看要删什么find . -name '*.tmp' -delete # 确认无误再删
-delete由 find 自己完成,不经过 shell,文件名再古怪也不会被拆错 习惯是先用-delete
man rm- GNU Coreutils – rm