本来今天不准备开电脑了,太困了,想睡觉,然而一哥们儿短信都发过来了,要问个问题,于是还是打开了电脑,没想到是一个很有代表性的问题,顺便也牵扯了前些天我的工作中的一个bug,值得记录下来。问题如下:
linux下,一个可执行文件exe1正在执行中,rm –f可以将其删除,mv可以将其移除,mv $other exe1也可以将其替换,但是cp $other exe1则显示文件忙,求解。
这实际上并不是一个真正的问题,因为只要你的基础知识扎实,这个问题显然很简单,原因只有一个,那就是linux文件基于引用计数。现在问题是这些个命令如何来操作一个文件的引用计数。下面的讨论都是基于独占打开的模式。
如果一个文件已经被打开,那么它的引用计数会增加1,如果调用了rm,实际上底层只是unlink了一下,也就是说将它的引用计数减少1,这样虽然你在界面上(命令行或者GUI)看不到它了,但是它被打开时的计数还在,只有当它被关闭的时候,引用计数变为0,才彻底删除它。
再说mv命令,它实际上只是一个源文件的rename而已,如果mv的目标本来就存在,那么在目标上执行一个类似rm的效果,也就是unlink一下,结合引用计数的理论,目标文件如果已经被打开,那么当关闭的时候将不复存在,如果本来就没有被打开,那么mv的时候,目标直接被删除,因为unlink之后,它的引用计数变成了0。
最后看一下cp命令,cp的话并不触动源文件和目标文件元数据本身(时间戳除外),它只是打开源文件和目标文件,在源文件上执行read,然后将结果write到目标文件,实质上是一个IO操作,对于可执行文件,是独占打开的,并不允许写入,因此会出错。
这里就不再列出内核源码了,可以自行参考系统调用的实现而加深理解,不过最好别干巴巴的看,还是结合strace以及objdump比较好,要知道是怎么以及什么时候调用的,以及调用参数是什么,否则就和八股文没区别了。那么这和我工作中的bug有什么关系呢?这个bug源于OpenVPN的日志记录,并且配置了日志回滚,回滚配置文件关键字段如下:
size 4M
missingok
rotate 9
compress
delaycompress
create 644 xx xx
…
结果当日志回滚成了vpn.log.1之后,这个vpn.log.1依然继续被写入。这个原因正是rename造成的。在logrotate的man页面中,有一个copytruncate配置,其含义就是不进行rename,而只是copy,然后将原来的文件truncate,加入这个就可以了。
千万不要小看这些很简单的命令,真正理解的人并不多,即使真正的理解,出现问题,能真正对应到原理也不多,很简单的东西如果能彻底做到透彻的理解并且活用,再往深入学习才是有意义的。
Linux中文件执行中的锁定怪现象解释
2019-12-02 16:56Linux教程网 Linux
linux下,一个可执行文件exe1正在执行中,rm –f可以将其删除,mv可以将其移除,mv $other exe1也可以将其替换,但是cp $other exe1则显示文件忙,求解
延伸 · 阅读
- 2024-11-03晨报:《龙腾4》Steam“多半好评” 《Apex》不再支
- 2022-03-11在Linux下通过命令行打包Android应用的方法
- 2022-03-10这个 Linux 图形计算器让数学很有趣
- 2022-03-10Linux下部署springboot项目的方法步骤
- 2022-03-10linux中把.c的文件编译成.so文件
- 2022-03-10Linux服务器下安装配置Nginx的教程
- Linux
Linux折腾记(二十二):虚拟机体验之Xen篇——令人脑洞大开的
这篇文章主要介绍了Linux折腾记(二十二):虚拟机体验之Xen篇——令人脑洞大开的奇异架构,在虚拟机领域,Xen具有非常高的知名度,其名字经常在各类文章...
- Linux
Linux下semop等待信号时出现Interrupted System Call错误(EINTR)解决方法
本篇文章是对在Linux下semop等待信号时出现Interrupted System Call错误(EINTR)的解决方法进行了详细的分析介绍,需要的朋友参考下...
- Linux
在 Linux 上使用 gImageReader 从图像和 PDF 中提取文本
gImageReader 是一个 GUI 工具,用于在 Linux 中利用 Tesseract OCR 引擎从图像和 PDF 文件中提取文本。...
- Linux
深入解析Linux下的磁盘缓存机制与SSD的写入放大问题
这篇文章主要介绍了深入解析Linux下的磁盘缓存机制与SSD的写入放大问题,设计到Linux的内核及线程等部分深度的知识,需要的朋友可以参考下...
- Linux
Linux系统中的访问控制:hosts.deny & hosts.allow
背景介绍 hosts.deny和hosts.allow是Linux系统中用于访问控制的重要工具,起源于TCP Wrapper软件,旨在提供对网络服务的访问控制。这两个文件在系统安全性方面...
- Linux
利用Linux高级IO实现非阻塞和多路复用IO
高级IO(Advanced IO)是一种在Linux系统中进行非阻塞和多路复用IO操作的技术。这种技术可以提高系统的并发处理能力,提升IO性能,并减少资源的消耗。下面...
- Linux
linux命令大全之telnet命令详解(linux远程登录)
telnet命令通常用来远程登录。telnet程序是基于TELNET协议的远程登录客户端程序。Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要...
- Linux
Linux系统一些重要的学习方法及路线图详解
对于Linux系统来说;一些学习方法及路线图是非常值得学习的,今天小编就为大家分享一下Linux系统一些重要的学习方法及路线图详解;有需要的朋友一起去...