共计 1519 个字符,预计需要花费 4 分钟才能阅读完成。
在 Linux 系统中,如果不小心误删除了应用程序正在使用的文件的话,可以在停止应用前通过 lsof
命令恢复被删除的文件。废话不多说,恢复过程见下文。
步骤
获取进程号
通过 ps
拿到进程号(假设应用程序为 appDemo):
$ ps axuf |grep appDemo
qileq 8932 4.9 13.2 64909644 43721472 ? Sl Jan20 867:59 /usr/java/default/bin/java com.qileq.appDemo
第二列的 8932
即进程号。
获取文件描述号
通过 lsof
查看指定进程被删除文件的文件描述符(假设被删除文件名为 app.log):
$ lsof -p 8932 |grep app.log
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 8932 qileq 1w REG 253,0 166029303 169140713 /home/qileq/demo/app.log~ (deleted)
java 8932 qileq 397w REG 253,0 166062569 169140713 /home/qileq/demo/app.log~ (deleted)
第四列即文件描述符,其值可能为如下两大类之一:
- 文件描述符值加字符的组合形式,其中字符有如下几种:
r
:表示应用程序从该文件读数据w
:表示应用程序向该文件写数据u
:表示应用程序读写该文件- 空格:读写模式未知且无锁
-
:读写模式未知但有锁
- 特定含义的字符串:
cwd
:当前工作目录Lnn
:库引用(AIX)err
:文件描述符的错误信息jld
:jail 目录(FreeBSD)ltx
:共享库文本(代码和数据)Mxx
:十六进制内存映射类型编号 xxm86
:DOS 合并映射文件mem
:内存映射文件mmap
:内存映射设备pd
:父目录rtd
:根目录tr
:内核 trace 文件 (OpenBSD)txt
:程序文本(代码和数据)v86
:VP/ix 映射文件
如果应用程序持有文件锁的话,则文件描述符还会使用如下字符表示持有的锁类型:
N
:持有未知类型的 Solaris NFS 锁r
:持有文件部分区域的读锁R
:持有整个文件的读锁w
:持有文件部分区域的写锁W
:持有整个文件的写锁u
:持有文件任意类型的读写锁U
:持有未知类型的锁x
:持有文件部分区域的 SCO OpenServer Xenix 锁X
:持有整个文件的 SCO OpenServer Xenix 锁- 空格:不持有锁
如常用的 FD 值有 8u
、mem
等样式的值,稍微复杂的值有 mem-W
、5uW
等类型。
恢复被删除文件
/proc/PID/fd/FD
即为被删除的文件,如上述例子中的 /proc/8932/fd/1
即表示其中一个被删除的日志文件。通过 cp
命令恢复该文件:
$ cp /proc/8932/fd/1 app.log.1
$ stat app.log.1
File: ‘app.log.1’
Size: 166460709 Blocks: 325120 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 169140672 Links: 1
Access: (0640/-rw-r-----) Uid: ( 1005/ qileq) Gid: ( 1005/ qileq)
Access: 2023-02-01 18:11:22.337483269 +0800
Modify: 2023-02-01 18:11:19.082499139 +0800
Change: 2023-02-01 18:11:19.082499139 +0800
Birth: -
重启应用
待恢复所有被误删除的文件后,最好还是将应用重启下,以免新生成的文件可能也处于被删除状态。
参考
正文完