当我们在Linux系统中卸载软件或清理数据时,经常会使用rm -rf命令去删除某个目录,例如删除/tmp/tektea目录:

# rm -rf /tm/tektea

rm命令的-r和-f这两个参数的man含义如下:

-r, -R, --recursive

remove directories and their contents recursively

-f, --force

ignore nonexistent files, never prompt

所以-r和-f分别表示可递归删除目录和强制删除文件,组合起来就是我们在Linux系统中所熟知的、最暴力的强制删除某个目录的命令了,即便目录下文件正在被读写,也依然会干干净净的删除掉该目录,因为有-f参数,听起来合情合理。但你现在已经看了本文的标题,你开始迷惑了吧?

没关系,下面我们通过一些测试来验证下这个暴力的 rm -rf 命令,看看它是不是真的那么生猛,可以破坏一切目录。

用例1:使用cp命令持续往/tmp/tektea目录下拷贝文件,然后rm -rf /tmp/tektea,测试代码如下

# cat test1.sh

#!/bin/bash

i=1

while true

do

cp /tmp/testfile /tmp/tektea/$i

let i++

done

# cat /tmp/testfile

hi

验证结果:执行bash test1.sh后,rm -rf /tmp/tektea删除成功。

用例2:使用dd命令持续往/tmp/tektea目录下写文件,然后rm -rf /tmp/tektea,测试代码如下

# cat test2.sh

#!/bin/bash

while true

do

dd if=/dev/zero of=/tmp/tektea/ddfile bs=1024 count=1000000000

let i++

done

验证结果:执行bash test2.sh后,rm -rf /tmp/tektea删除成功。

用例3:使用echo命令持续往/tmp/tektea目录下的文件写数据,然后rm -rf /tmp/tektea,测试代码如下

# cat test3.sh

#!/bin/bash

while true

do

echo hi >>/tmp/tektea/echofile

done

验证结果:执行bash test3.sh后,rm -rf /tmp/tektea删除失败,且有以下报错:

# rm -rf /tmp/tektea/

rm: cannot remove `/tmp/tektea': Directory not empty

通过上面的验证,首先我们可以得出这条结论:使用rm -rf命令删除目录时,如果该目录下的文件正在被写入,那么会存在删除失败的可能。

那么,以上三个用例都是在往/tmp/tektea目录写入数据,为什么仅仅是第三个场景会失败呢?

各种迹象都把根因指向到了 rm 命令(有兴趣的朋友可以下载Linux中rm命令的源码走读下),rm命令在-r -f强制删除目录时,其逻辑是这样的:

1)从被删除目录的最里层递归删除文件;

2)当最里层目录A的文件被删除完以后,再删除该层文件夹A;

3)在删除文件夹A前,再检查目录A下是否还有文件,如果有则报错Directory not empty(编外:注意这里了)

现在再来回答这个问题——“为什么仅仅是第三个场景会失败呢?”,不过在回答前,我先给大家展示两个数据:

1. 用例1使用cp往/tmp/tektea目录拷贝数据,15秒大约生成了8600个文件,每秒约573文件,相当于每秒573次写入

2. 用例3使用echo往/tmp/tektea/echofile写数据,15秒大约在echofile中写入了59万行,每秒约40000次写入

所以结合rm的实现和几个用例差异可以清楚的知道——在删除某个目录时,若有进程往该目录写入数据,则需要先停止该进程的服务(或kill掉该进程),所以我们的一些Shell代码在卸载或删除目录时就存在失败的可能。

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信