45gfg9
本帖最后由 45gfg9 于 2020-8-29 18:16 编辑
今天在鱼塘讨论在茶馆发rm -rf会怎么样


好!箱子今天就来科普下rm的用法
可能是你坛第一个rm教程
Note: 命令执行环境为macOS 10.14.6,shell为zsh


1 - 一看usage
  1. # 45gfg9 @ 45gfg9-imac in ~ [20:24:20]
  2. $ rm
  3. usage: rm [-f | -i] [-dPRrvW] file ...
  4.        unlink file

  5. # 45gfg9 @ 45gfg9-imac in ~ [20:24:21] C:64
复制代码

于是我们可以得知:
  • 参数有 f i d P R r v W,后跟文件名
  • -f和-i不能同时使用
  • 作用是unlink file(取消链接文件(删除(?
  • 不指定操作参数(file),返回64

日常使用中不需要参数:
  1. # 45gfg9 @ 45gfg9-imac in ~ [20:35:35]
  2. $ rm yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [20:35:38]
复制代码

同时,~下的yys.ysjs没了
于是又可以得知:
  • 文件成功删除,返回0

那,如果删除不成功呢?
a) 文件不存在
我们再来删一次yys.ysjs看看:
  1. # 45gfg9 @ 45gfg9-imac in ~ [20:35:38]
  2. $ rm yys.ysjs
  3. rm: yys.ysjs: No such file or directory

  4. # 45gfg9 @ 45gfg9-imac in ~ [20:37:02] C:1
复制代码

此时没有文件受到影响
于是我们又知道:
  • 文件不存在时,返回1

b) Case 2: 权限不足
我们来创建一个属于root:wheel的yys.ysjs:
  1. # 45gfg9 @ 45gfg9-imac in ~ [20:37:02] C:1
  2. $ touch yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [20:48:12]
  4. $ sudo chown root:wheel yys.ysjs
  5. Password:

  6. # 45gfg9 @ 45gfg9-imac in ~ [20:48:22]
  7. $ rm yys.ysjs
  8. override rw-r--r--  root/wheel for yys.ysjs? y

  9. # 45gfg9 @ 45gfg9-imac in ~ [20:48:30]
复制代码

注意到rm时会提示是否override,我们回答了y(es)
发现yys.ysjs被删除了
于是:
  • rm可以移除任何用户文件,只要override有待考证

那系统文件呢?
  1. # 45gfg9 @ 45gfg9-imac in ~ [20:58:03]
  2. $ rm /bin/bash
  3. override r-xr-xr-x  root/wheel restricted,compressed for /bin/bash? y
  4. rm: /bin/bash: Operation not permitted

  5. # 45gfg9 @ 45gfg9-imac in ~ [20:58:10] C:1
复制代码

注意到系统文件有额外的flag:restricted,compressed,以及删除失败,Operation not permitted
  • 系统文件无法正常删除(删除失败返回1)

现在我们是删文件,如果我们想删文件夹呢?
c) Case 3: 删除文件夹(空)
比如我前一秒mkdir了一个文件夹,后一秒就发现不需要了:
  1. # 45gfg9 @ 45gfg9-imac in ~ [20:58:50]
  2. $ mkdir ljyys

  3. # 45gfg9 @ 45gfg9-imac in ~ [21:05:22]
  4. $ rm ljyys
  5. rm: ljyys: is a directory

  6. # 45gfg9 @ 45gfg9-imac in ~ [21:05:24] C:1
复制代码

OH MY GOD! 没删掉!这怎么整!
别忘了,遇事不决先看man
rm当然没有低级到只能删文件
2 - 二看man
刷屏警告
  1. # 45gfg9 @ 45gfg9-imac in ~ [21:05:24] C:1
  2. $ man rm
复制代码


我们看到啦!rm,同时也叫unlink,用于remove directory entries
我们发现了参数-d: Attempt to remove directories as well as other types of files.
用它来删我们没删掉的文件夹试试:
  1. # 45gfg9 @ 45gfg9-imac in ~ [21:12:40]
  2. $ rm -d ljyys

  3. # 45gfg9 @ 45gfg9-imac in ~ [21:12:43]
复制代码

好!ljyys没啦!

可是,还记得么,ljyys是我们mkdir出来马上就要删的文件夹
如果是个非空的文件夹呢?
  1. # 45gfg9 @ 45gfg9-imac in ~ [21:16:51]
  2. $ mkdir lj

  3. # 45gfg9 @ 45gfg9-imac in ~ [21:16:54]
  4. $ touch lj/yys

  5. # 45gfg9 @ 45gfg9-imac in ~ [21:16:56]
  6. $ rm -d lj
  7. rm: lj: Directory not empty

  8. # 45gfg9 @ 45gfg9-imac in ~ [21:16:59] C:1
复制代码

啊这,删除又失败了
折回去看man!
再 放 送

看到了-R:
  • Attempt to remove the file hierarchy rooted in each file argument. 那么我们知道加了-R会移除整个文件树
  • The -R option implies the -d option. 那么我们可以写 rm -R而不必 rm -d -R
  • -r: Equivalent to -R. 那么-r和-R效果等同

来试试:
  1. # 45gfg9 @ 45gfg9-imac in ~ [21:16:59] C:1
  2. $ rm -r lj

  3. # 45gfg9 @ 45gfg9-imac in ~ [21:21:39]
复制代码

好!lj整个没了!yys也没了!
d) 我们找的-f呢?
回去看man,发现了我们要找的-f: Attempt to remove the files without prompting for confirmation, regardless of the file's permissions.
之前我们删root/wheel的yys.ysjs时提示override,如果加了-f呢:
  1. # 45gfg9 @ 45gfg9-imac in ~ [21:21:39]
  2. $ touch yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [21:26:24]
  4. $ sudo chown root:wheel yys.ysjs
  5. Password:

  6. # 45gfg9 @ 45gfg9-imac in ~ [21:26:32]
  7. $ rm -f yys.ysjs

  8. # 45gfg9 @ 45gfg9-imac in ~ [21:26:35]
复制代码

yys.ysjs又没了
那么我们发现 -f可以不用确认override直接删除
小提示:标准Unix命令中,单字参数可以合并,比如 rm -r -f可以写成rm -rf

好,已经够了
至此,我们得出了rm -rf /的作用:递归,并强制删除根目录/的文件树(即整个文件系统)
顺便说一下,有的Linux系统不允许直接删除/以防止误操作,你需要加--no-preserve-root参数才能强行删掉。对了,别忘了sudo



4 - 其他flags
再看看man(没有再放送了,放心),我们还有哪些参数没有提到?
i P v W
e) -f:还没说完呐
man中对于-f参数的说明:
  • Attempt to remove the files without prompting for confirmation, regardless of the file's permissions. √已验证
  • If the file does not exist, do not display a diagnostic message or modify the exit status to reflect an error. ?未验证
  • The -f option overrides any previous -i options. ?未验证

-i我们之后马上说,现在先来看第二项
我们拿之前的yys.ysjs来试试
  1. # 45gfg9 @ 45gfg9-imac in ~ [21:50:09]
  2. $ touch yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [21:50:29]
  4. $ rm -f yys.ysjs

  5. # 45gfg9 @ 45gfg9-imac in ~ [21:50:32]
  6. $ rm -f yys.ysjs

  7. # 45gfg9 @ 45gfg9-imac in ~ [21:50:43]
复制代码

发现了么?第二次rm -f时,yys.ysjs已经不存在了
可是吐出错误No such file or directory了么?没有
返回代表删除失败的1了么?也没有
所以,第二项验证成功√
下面是第三项...
f) -i:确认所有文件
从usage我们看到:(再 放 送)
  1. $ rm
  2. usage: rm [-f | -i] [-dPRrvW] file ...
  3.        unlink file
复制代码

即-f和-i不能同时使用
从man中我们看到,对于-i参数:
  • Request confirmation before attempting to remove each file, regardless of the file's permissions, or whether or not the standard input device is a terminal.
  • The -i option overrides any previous -f options.

来,传统测试
  1. # 45gfg9 @ 45gfg9-imac in ~ [21:53:41]
  2. $ touch yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [21:53:43]
  4. $ rm -i yys.ysjs
  5. remove yys.ysjs? n

  6. # 45gfg9 @ 45gfg9-imac in ~ [21:53:46]
  7. $ rm -i yys.ysjs
  8. remove yys.ysjs? y

  9. # 45gfg9 @ 45gfg9-imac in ~ [21:53:49]
复制代码

注意到,即使yys.ysjs是我们刚刚touch的文件,即保证在删除权限方面没有问题,rm还是询问我们是否删除yys.ysjs
所以-i即在删除时确认每个文件
可以想象到,在删某个文件夹时,rm -ri会让你有非常舒适的删除体验 :D

对了,-f的第三项我们还没有验证呢!
  1. # 45gfg9 @ 45gfg9-imac in ~ [22:10:01]
  2. $ touch yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [22:10:11]
  4. $ sudo chown root:wheel yys.ysjs
  5. Password:

  6. # 45gfg9 @ 45gfg9-imac in ~ [22:10:23]
  7. $ rm -fif yys.ysjs

  8. # 45gfg9 @ 45gfg9-imac in ~ [22:10:27]
复制代码
  1. # 45gfg9 @ 45gfg9-imac in ~ [22:10:27]
  2. $ touch yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [22:10:41]
  4. $ rm -ifi yys.ysjs
  5. remove yys.ysjs? y

  6. # 45gfg9 @ 45gfg9-imac in ~ [22:10:49]
复制代码

已经数不清第几次钷氦ljyys了(跑
所以-i会取消之前出现的所有-f的效果,反之亦然
我们叫它们互斥参数吧XD

g) -P:删掉就不要想恢复了.jpg
-P的介绍:
  • Overwrite regular files before deleting them.
  • Files are overwritten three times, first with the byte pattern 0xff, then 0x00, and then 0xff again, before they are deleted.

于是:
  • 文件在删除前先被覆写(同时我们也得知不带-P的rm只会删除文件的存在,而不会真正擦除硬盘上的文件内容
  • 文件被填充三次:第一次0xff,第二次0x00,第三次0xff,这之后想恢复文件基本不可能了

这个就没什么好演示的了:
  1. # 45gfg9 @ 45gfg9-imac in ~ [22:03:07]
  2. $ touch yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [22:03:15]
  4. $ rm -P yys.ysjs

  5. # 45gfg9 @ 45gfg9-imac in ~ [22:03:23]
  6. $ rm -fP yys.ysjs

  7. # 45gfg9 @ 45gfg9-imac in ~ [22:03:27]
复制代码

h) -W 恢复文件(能用?)
man的介绍:
  • Attempt to undelete the named files.
  • Currently, this option can only be used to recover files covered by whiteouts.

whiteout是什么?我不知道
在本使用例,-W并没有生效:
  1. # 45gfg9 @ 45gfg9-imac in ~ [22:05:51]
  2. $ echo LJYYS > yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [22:05:58]
  4. $ rm yys.ysjs

  5. # 45gfg9 @ 45gfg9-imac in ~ [22:06:04]
  6. $ rm -W yys.ysjs
  7. rm: yys.ysjs: Operation not supported

  8. # 45gfg9 @ 45gfg9-imac in ~ [22:06:08] C:1
复制代码

所以有人告诉我-W怎么用嘛,这教程写不下去了(
i) -v:每一个文件都看得清清楚楚
man对-v的介绍:Be verbose when deleting files, showing them as they are removed.
详细输出嘛,这个我熟!
我们先随便抓一个yys.ysjs:
  1. # 45gfg9 @ 45gfg9-imac in ~ [22:32:11]
  2. $ touch yys.ysjs

  3. # 45gfg9 @ 45gfg9-imac in ~ [22:32:33]
  4. $ rm -v yys.ysjs
  5. yys.ysjs

  6. # 45gfg9 @ 45gfg9-imac in ~ [22:32:36]
复制代码

输出了实际删除的文件:yys.ysjs
接着抓一个文件夹好了
  1. # 45gfg9 @ 45gfg9-imac in ~ [22:32:00]
  2. $ tree TrashBin
  3. TrashBin
  4. ├── 45gfg9
  5. └── yinyangshi

  6. 0 directories, 2 files

  7. # 45gfg9 @ 45gfg9-imac in ~ [22:32:03]
  8. $ rm -rv TrashBin
  9. TrashBin/45gfg9
  10. TrashBin/yinyangshi
  11. TrashBin

  12. # 45gfg9 @ 45gfg9-imac in ~ [22:32:11]
复制代码

注意到我们有一个文件夹TrashBin,里面有45gfg9和yinyangshi两个文件
执行rm -rv TrashBin后,先删除了TrashBin中的两个文件,后删除了TrashBin文件夹
-f来!
  1. # 45gfg9 @ 45gfg9-imac in ~ [22:35:18]
  2. $ rm -v yys.ysjs
  3. yys.ysjs

  4. # 45gfg9 @ 45gfg9-imac in ~ [22:35:23]
  5. $ rm -vf yys.ysjs

  6. # 45gfg9 @ 45gfg9-imac in ~ [22:35:27]
复制代码

我们发现,虽然-f压制了文件不存在的信息,可是-v也没告诉你有文件被删除了啊
高,实在是高

5 - 其他补充信息
参数列表的后面,还提到了:
  • The rm utility removes symbolic links, not the files referenced by the links. 移除符号链接,而不是符号链接指向的文件
  • It is an error to attempt to remove the files ``.'' or ``..''. 删除.(当前目录)和..(上层目录)不被允许
  • When the utility is called as unlink, only one argument, which must not be a directory, may be supplied. No options may be supplied in this simple mode of operation, which performs an unlink(2) operation on the passed argument. 即,unlink可视作rm的简单(垃圾)版本,只能删除文件,不能提供参数
  • The rm utility exits 0 if all of the named files or file hierarchies were removed, or if the -f option was specified and all of the existing files or file hierarchies were removed. If an error occurs, rm exits with a value >0. 这就解释了返回值的问题,返回非0就代表一定有错误发生

man中的其他部分,如NOTE和BUGS,解释了其他关于rm的信息。
在NOTE中我们看到:
The rm command uses getopt(3) to parse its arguments...
getopt是一个很有用的命令行函数,用于解析命令行参数
这也是它的名称来源:get options
如果文件名以-开头就麻烦了,rm -filename会解析为-f -i -l -e -n -a -m -e参数,那你就炸掉了
所以有一个handy的小东西:--
我们来看完那一段:
     The rm command uses getopt(3) to parse its arguments, which allows it to accept the `--' option which will cause it to stop processing flag options at that point.  This will allow the removal of file names that begin with a dash (`-').  For example:
           rm -- -filename

就可以专门对付这种-开头的文件名情况了

BUGS中,也有说关于-P的内容:
BUGS
     The -P option assumes that the underlying file system is a fixed-block file system.  In addition, only regular files are overwritten, other types of files are not.

也就是说,像unix socket文件之类的,-P是不会删除的

6 - 水帖完毕,积分+2,溜了
中途手残发出草稿了 冒冒失失补完了-r和-f的内容
而且还有错误,我也暂时无法验证
太丢人了.jpg
基本上就这样了 (?) 还有哪里有问题么

下次出个什么呢,cd教程?(

AzureZeng
rm -rf 删目录特别爽。

PercyDan
我还知道

夕兽
管理员 温馨提醒您:
1) 尊重别人的隐私。
2) 输入前要先考虑(后果和风险)。
3) 权力越大,责任越大。

[管理系统 提醒您] > 事项千万条,细心第一条。sudo rm -rf ./*不规范,漏"."两行泪

𝐄𝐚𝐫𝐥
完全看不懂
我还是画好我的像素画吧

贴贴迷离
yys.ysjs好评

儚无水木
好的,学到了,这就去试试
写了那么多,辛苦啦

src_resources
rm温馨提醒您:在'/' 进行递归操作十分危险,使用 --no-preserve-root 选项跳过安全模式

lawye0
我一般不加f,就sudo rm -r 文件夹, 怕删了什么不该删的

囗il
/不知道
/太长了,懒得看
/看不懂

回去鱼塘骂ljyys不香吗?