当前位置: 首页 > Linux

linux下删掉一些日志也能要人的

时间:2023-04-06 04:33:00 Linux

想了十几天十夜,不知道写什么好,还是写面试题吧。1面试应聘者时,经常会问:Linux下如何删除某个目录下的所有日志文件?不知道是不是因为我那无害的笑声,给应聘者一种我好对付的错觉,以至于应聘者都回答:rm*。文件也会被删除吗?答案:rm-r*.log2令我惊讶的是,很少有考生真正想到find命令。而且想起来的人很少记得具体用法。到目前为止,只有一位候选人可以给出完整的命令:find-name\*.log-execrm-f{}\;注意:这里的两个斜杠不是错别字。我不认为find应该被认为是一个非常罕见的命令?我们共享开发机,因为大家都懒得删日志,经常磁盘满了,然后我们给它加了一个crontab:04***find/home/-typef-name"*.log*"-size+100M-execbash-c"echo-n>'{}'"\;注意:".log*"后面的*是考虑logrotate。注意这个命令并没有使用rm,而是使用了重定向清空文件,后面会解释原因。3基于清理磁盘空间的场景,继续追问:大家有没有遇到过日志文件已经删除,但是磁盘空间还没有释放的情况?可能有的考生心里在想:文件删了就删了,还有什么磁盘空间没有释放?所以有时我需要解释一下,是df命令没有看到磁盘空间减少。另一位考生苦思冥想,跟我确认了一下,是不是只是这个目录挂载到了其他磁盘上,所以貌似当前磁盘空间并没有减少。(当然不是)心胸开阔一点的考生会想:你这白痴,你不是删了软链接吗?当然,候选人的语气会更友好。那我就继续跟考生交流:你说的是软链接,那么它和硬链接有什么区别呢?有时候我怀疑这些连续的问题会让考生开始怀疑人生,因为有的考生有点犹豫,认为自己想讲的其实是一个hardlink。但是,仍然有少数考生知道软链接是一种文件,其内容是目标文件的路径;硬链接是一个inode的别名,同一个inode可以有多个链接,硬链接的个数记录在inode中(引用计数)。例如:创建一个空文件,查看inode和链接数:$toucha.txt#创建一个空文件$stat-c'inode%i,links%h'a.txtnode12058942,links1创建一个softlink,再看文件大小:$ln-sa.txtb.txt#softlink$stat-c'inode%i,links%h'b.txtnode12058978,links1$ls-lb.txt#size5wordsSectionlrwxrwxrwx...5...b.txt->a.txt$readlinkb.txt#文件内容a.txt创建硬链接,查看inode数和链接数$lna.txtc.txt#硬链接,inode不变,链接数变成2$stat-c'inode%i,links%h'c.txtnode12058942,links2$ls-lc.txt#size0字节,一样asalrwxrwxrwx...0...c.txt4但在实际生产中,遇到“日志文件被删除,但空间未释放”,通常与软/硬链接无关。动手经验多的人就会知道,这往往是因为日志文件正在被另一个进程打开。比如在终端1中打开a.txt:$python>>>f=open("a.txt")那么在终端2中可以看到文件被Python打开了:$lsofa.txtCOMMANDPID...节点名称python2390。..12058942a.txt删除a.txt,然后查看python打开的文件列表:$rma.txt$ls-l/proc/2390/fdlrwx------1user...00:040->/dev/pts/5lrwx-----1个用户...00:041->/dev/pts/5lrwx------1个用户...00:042->/dev/pts/5lr-x------1user...00:043->/tmp/a.txt(删除)注:0,1,2,3是内核的fd号.0=标准输入,1=标准输出,2=标准输出。可以看出a.txt被标记为删除,但是由于进程还处于打开状态,可能会访问文件内容,所以内核会等到进程关闭文件(或者进程退出)后才删除文件从磁盘。5在面试中,通常没有机会再问更多的问题,但在实践中,问题往往得不到解决。比如前面提到的共享开发机就曾经遇到过磁盘总空间为800G的情况,但是用du命令查看,所有文件只占用了500G。那么:1、如何知道系统中有哪些文件被删除了但还被占用?$须藤lsof|grepdeletedCOMMANDPID...NAMEmain893246.../../nohup.out(deleted)...发现有大量的nohup.out已经被删除了,但是仍然被某些进程打开。2、洞找到了,怎么填?由于这是开发机,所以很简单,杀掉进程即可。当进程退出时,内核会负责关闭文件并清理占用的空间。但是在线服务呢?Linux下有一个叫logrotate的包,它被nginx之类的服务用来做日志的切割/轮转。但是nginx在后台持续运行,不能为了切一个log就停止服务,所以他们约定:logrotate执行rename系统调用(相当于mv命令)重命名日志文件;由于inode没有变化,nginx会继续写入改名后的日志文件;logrotate向nginx发送SIGHUP信号;nginx收到信号后会关闭当前文件,并重新打开日志文件(即新建一个日志文件)。注:为什么用SIGHUP而不用其他信号,以后可能会另开一讲。这样logrotate产生的日志就可以放心删除了。不支持类似逻辑的服务呢?重启大法。如果不怕背P0,可以这样做:$sudogdb(gdb)attach$PID(gdb)callftruncate(3,0)#根据需要修改fd$1=0注意:好像文件被清空了,但可能还有其他坑,后果自负。ftruncate只是清除文件。如果要关闭文件,可以结合dup、dup2、open和close来搞定,这里不再赘述。6看到这里你应该明白前面的find命令为什么不直接使用rm了吧?像往常一样总结:您可以使用find来查找文件。软链接存储路径,硬链接共享inode。删除进程打开的文件,磁盘空间不会释放。lsof很好用(不仅仅是看文件的占用),还想知道面试题其他有意思的东西?不如投递简历亲自体验一下:~投递链接~外卖研发工程师(上海)https://job.toutiao.com/s/J8D...高级广告研发工程师(北京)https://job.toutiao.com/s/J8D...欢迎关注