代码改变世界

Linux命令 lsof使用 文件删除但是空间未被释放

2015-04-03 17:21  youxin  阅读(953)  评论(0)    收藏  举报

lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。

lsof +d /usr/local   显示当前目录下被进程打开的文件

lsof +D /usr/local  显示当前目录下被进程打开的文件,包括其他目录下的文件

lsof file           显示开启file的进程

lsof -c abc     显示abc进程打开的文件

lsof -p 123     显示pid为123的进程所打开的文件

lsof -g gid      显示归属gid的进程情况

lsof -u root     显示用户root的进程所打开的文件

lsof -u ^root   显示不是用户root的进程所打开的文件

lsof -u 1000   显示uid为1000的用户的进程所打开的文件

lsof -i          显示所有打开的端口

lsof -i:80    显示所有打开80端口的进程

lsof -i udp@192.168.129.126:5060   显示哪些进程使用udp打开了192.168.129.126的5060端口

lsof -i tcp@192.168.129.126:ftp -r      显示哪些进程使用tcp打开了192.168.129.126的ftp服务,-r不断查看

http://blog.csdn.net/guoguo1980/article/details/2324454

 

lsof - 根据 fd 或 socket 查找打开的文件或读写地址

 

Linux下 文件删除但是空间未被释放 或者 磁盘已满但找不到对应的大文件 的解决方案

 

linux磁盘空间已满,手动rm -rf 删除了大文件之后,df -h 查看一下发现空间占用还是不变,有时候会想rm -rf 删除只是逻辑删除到回收站一样?其实不然,通常这种情况都是文件被删除,但是还被进程占用,因此删除文件空间未释放

通常的建议是kill 掉对应的进程,但是如果是生成环境,不能轻易kill进程的话,可以通过置空文件的方式来释放空间

通过lsof | grep deleted 找到未能删除掉的文件,确定占用的进程号
通过 ls -l /proc/PID/fd/* | grep 文件名,找到相应文件句柄
清除文件内容 echo > /proc/PID/fd/FD_NUM

此操作不会删除文件,而是将文档内容清空的方法释放空间,文件仍存在

# 查看磁盘占用 df -h # 创建1个5000MB的文件 dd if=/dev/zero of=/delete.tmp bs=1000MB count=5

 

或者直接kill进程

进程名   PID       USER    FD   文件类型        大小(字节)  索引节点  文件名  [(状态)]

       3311    AuSP    8w      REG              253,0         778   10879268 ***.log (deleted)

状态为deleted为标记被删除,其实该文件并没有从磁盘中删除,类似windows下的回收站状态。

据称当有其他进程打开某文件时文件被删除,就会将该文件标记为deleted,并删除其目录节点。使用du查看时,因为没有该删除状态文件的节点信息,所以就不做统计,从而导致与df的结果不一致。

若要将deleted状态文件删除,则根据pid直接kill调相应进程即可。

 

 

 

2. 模拟进程占用

这里使用tail -f 命令对文件进行占用

tail -f /delete.tmp

执行rm -rf 命令删除文件

下图可以看到,由于文件被占用,执行删除命令成功后仍然没有释放空间

# 查看磁盘占用
df -h
# 删除创建文件
rm -f /delete.tmp

# 查看磁盘占用
df -h

查看被删除但是未释放空间的文件

通过执行以下命令,可以看到tail 进行占用了delete.tmp文件,文件大小5GB

lsof | grep deleted 



执行清空文件操作
语法:

# 通过PID查看文件句柄
ll /proc/PID/fd | grep delete.tmp

# 将指定进程下文件句柄的文件置空
echo > /proc/PID/fd/文件句柄
1
2
3
4
5
示例:

# 查看pid为17271的文件句柄
ll /proc/17271/fd | grep delete.tmp

# 置空文件
echo > /proc/17271/fd/3
————————————————

、巧用losf恢复已删除文件

利用lsof可以恢复一些系统日志,前提是这个进程必须存在,具体请参考下面实验步骤

[root@192 ~]# echo "Lsof test" >lsof.log
[root@192 ~]# tail -f lsof.log &
[3] 9933
[root@192 ~]# Lsof test

按照上面所示,我们创建文件lsof.log,然后使用tail命令产生一个后台进程

[root@192 ~]# ls
anaconda-ks.cfg  install.log  install.log.syslog  lsof.log
[root@192 ~]# rm -rf lsof.log 
我们删除lsof.log文件,然后losf | grep lsof.log
[root@192 ~]# lsof |grep lsof.log
tail      9933      root    3r      REG                8,2        10     391018 /root/lsof.log (deleted)

从进程占用上可以看出

PID:9933 FD:3 那我们有直接进入/proc/9933/FD/3查看一下

已经将文件重定向恢复到原路径

[root@192 fd]# cat /root/lsof.log 
Lsof test

数据恢复完成,注意这个是有前提条件哦,占用进程需要存在。

 恢复文件

恢复文件

利用lsof可以恢复一些系统日志,前提是这个进程必须存在。这里就拿最常用的/var/log/messages来举例说明,大家在做测试的时候最好先备份一下。

#备份
shell> cp /var/log/message /var/log/message_bac
shell> lsof |grep /var/log/message
rsyslogd   1737      root    1w      REG                8,2   5716123     652638 /var/log/messages

 

进程在运行中,接下来我就把/var/log/messages这个文件删掉

shell> rm /var/log/messages

 

删掉之后,我再来看看这个进程的变化

shell> lsof |grep /var/log/messages
rsyslogd   1737      root    1w      REG                8,2   5716123     652638 /var/log/messages (deleted)

大家看到有变化了吧, 对比两个之后发现多了(deleted)。要找到这个文件在哪还要看看这个

PID:1737 FD:1 那我们有直接进入/proc/1737/FD/1用ll查看一下

shell> cd /proc/1737/fd/
shell> ll

total 0
lrwx------ 1 root root 64 Dec 23 13:00 0 -> socket:[11442]
l-wx------ 1 root root 64 Dec 23 13:00 1 -> /var/log/messages (deleted)
l-wx------ 1 root root 64 Dec 23 13:00 2 -> /var/log/secure
lr-x------ 1 root root 64 Dec 23 13:00 3 -> /proc/kmsg
l-wx------ 1 root root 64 Dec 23 13:00 4 -> /var/log/maillog

 

看到了1对应/var/log/messages (deleted),看看文件是不是我们要的文件:

shell> head -5 1
Nov 14 03:11:11 localhost kernel: imklog 5.8.10, log source = /proc/kmsg started.
Nov 14 03:11:11 localhost rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="1241" x-info="http://www.rsyslog.com"] start
Nov 14 03:11:11 localhost kernel: Initializing cgroup subsys cpuset
Nov 14 03:11:11 localhost kernel: Initializing cgroup subsys cpu
Nov 14 03:11:11 localhost kernel: Linux version 2.6.32-431.el6.x86_64 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013

 

对比备份文件:

shell> head -5 /var/log/message_bac
Nov 14 03:11:11 localhost kernel: imklog 5.8.10, log source = /proc/kmsg started.
Nov 14 03:11:11 localhost rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="1241" x-info="http://www.rsyslog.com"] start
Nov 14 03:11:11 localhost kernel: Initializing cgroup subsys cpuset
Nov 14 03:11:11 localhost kernel: Initializing cgroup subsys cpu
Nov 14 03:11:11 localhost kernel: Linux version 2.6.32-431.el6.x86_64 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013

对比发现数据是一样的,恢复

shell> cat 1 > /var/log/messages

再次提醒,恢复前提是这个进程必须存在。


原文链接:https://blog.csdn.net/qq_29864051/article/details/131337429