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 查找打开的文件或读写地址
通过日志发现某个进程一直阻塞在某处,通过 strace 查看系统调用:
$ strace -p 9441
Process 9441 attached
recvfrom(22,
- 1
- 2
- 3
发现阻塞在读 22 socket 上,由于进程连接的地址非常多,想通过目前的信息找到进程是阻塞在哪类连接的读取上:
$ lsof -p 9441 | grep 22u
python 9441 userxxx 22u IPv4 1546555902 0t0 TCP HOST_NAME:59973->IP:40014 (ESTABLISHED)
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
浙公网安备 33010602011771号