Linux下删除正在写入的文件会发生什么?

您所在的位置:网站首页 linux怎么删除创建的文件内容 Linux下删除正在写入的文件会发生什么?

Linux下删除正在写入的文件会发生什么?

2024-05-27 22:30| 来源: 网络整理| 查看: 265

一、成功“删除”了一个正在写入的文件!

某日,我启动了一个进程,向一个文件a.txt中写入内容,但不小心在另一个窗口用命令rm -f a.txt把它删除了,我以为这应该会触发一个警告,比如“不能删除一个打开的正在写入的文件”之类的,结果命令干脆的执行成功了,更出乎预料的是,我回到之前的那个窗口,我发现进程还在正常的写入数据,程序并没有报出任何异常,并打印出了一批批成功写入的日志。

二、为什么会这样?

这就有点让我费解了,伟大的好奇心让我寻找答案。原来Linux中真正表示一个文件的是一个叫inode的数据结构,而文件名只是指向了inode(自然能够想到可以有多个文件名指向同一个inode,这就是文件系统中的硬连接)。用rm -f a.txt这样的命令删除文件,其实是删除了文件名到inode之前的连接关系,那么直接表示文件内容的inode是什么时候删除的呢?答案是文件系统判断如果所有由文件名指向inode的关系都被删除的时候,就把inode删除掉。

        那似乎还是说不通,我上面并没有给a.txt建立硬链接,也就是a.txt的inode应该马上被删除,inode都没有了,写入进程应该报错才是啊,最后我通过查看教学版操作系统xv6的源码,发现其实文件系统在回收inode时,除了判断到inode的链接数为0,还要判断到inode的引用数为0,当一个进程打开一个文件时,它的inode的引用数就会加1,所以这里虽然链接数为0但引用数为1,文件系统还是不会删除inode,那么什么时候删除inode呢,答案是进程结束时引用数归0时。这也是为什么,有时我们将一个文件删除了,但是用du命令查看空间并没有被释放,重启程序空间就释放了的原因。

三、这些文件还会占用磁盘空间吗?

那么问题来了,如果我这个进程持续的写入,这些写入的内容会占用磁盘空间吗? 实践出真知,我们做一个小实验,在vmware中加一块小硬盘,空间为50M(vmware以G为单位,写0.05G),这样可以比较容易的模拟出磁盘写满的情形。通过fdisk命令进行分区

使用mkfs命令进行格式化,然后mount命令将其挂载到/test

mkfs -t ext3 /dev/sdb1 mkdir /test mount /dev/sdb1 /test

准备工作完毕! 这样,我们就得到了一个空间只有大概50M的文件夹,进入/test目录,写个简单的python脚本向a.txt文件写入内容:

import time fd = open("a.txt", "wb") time.sleep(3) while True: try: fd.write("xxx") fd.flush() except Exception,e: print(e) break time.sleep(1000) fd.close()

稍微解释一下代码: 在打开文件后,写入文件前sleep 5秒,这样可以让我们从容的启动另一个窗口,将a.txt删除,造成写入一个“不存在文件” 的情形。中间那个异常的捕获,是为了当磁盘写满时跳出循环,让程序休眠,否则它会退出(进程结束,空间就会被释放,观察不到实验现象了)

正式开始,python a.py启动程序,快速打开另一个窗口,rm -f a.txt删除文件,切换回之前窗口,静静的观察即将发生的一切。结果不出预料,磁盘很快被写满,程序打印出“[Errno 28] No space left on device”(注意这时进程并没有结束,而是被sleep冻住了)

 

 这时我们观察一下磁盘的使用情况,会发现磁盘确实被占满了

 我们也可以写入一个文件验证一下,同样报错:

 但是如果我们用du命令看,会发现/test的空间只有16k,这说明du命令并没有统计这种inode没有删除的文件

四、这些文件的内容还可以看到吗?

另外一个问题,这时我们能从哪里看到这个文件呢,因为我们已经无法通过之前的路径的方式了,其实还是可以的,因为操作系统会将进程打开的文件描述符放到/proc/{pid}/fd目录下,我们可以在这里看到这个文件的内容

五、可以重新“链接”回来吗?

还有一个问题,是否我们可以通过将一个文件名重新链接到这个inode的方式重新“找回”这个文件呢?(复制是可以的,但复制只有当前的内容,无法获取到之后写入的内容)答案似乎是不可以,因为这样是绕过了文件系统的权限机制,操作系统不允许。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3