演示误删操作
# 查看我们要演示的Java程序(随便一个都可以)
[root@Aspirant file_system]# ll
总用量 28264
-rwxr-xr-- 1 root root 28941538 2月 22 11:20 a.jar
# 在后台运行我们的Java程序,并重定向输出日志到log.txt
[root@Aspirant file_system]# nohup java -jar a.jar > log.txt 2>&1 &
[1] 32008
# 看下我们的Java程序的运行状态
[root@Aspirant file_system]# ps -aux|grep a.jar
root 32008 48.2 8.0 3522708 313460 pts/0 Sl 11:38 0:10 java -jar a.jar
root 32398 0.0 0.0 112824 1000 pts/0 S+ 11:38 0:00 grep --color=auto a.jar
# 再看看日志是否OK
[root@Aspirant file_system]# tail -f log.txt
2022-02-22 11:38:31.664 INFO 32008 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/api] : Initializing Spring embedded WebApplicationContext
2022-02-22 11:38:31.664 INFO 32008 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2127 ms
_ _ |_ _ _|_. ___ _ | _
| | |\/|_)(_| | |_\ |_)||_|_\
/ |
3.3.2
2022-02-22 11:38:33.024 INFO 32008 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2022-02-22 11:38:33.451 INFO 32008 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator'
2022-02-22 11:38:33.515 INFO 32008 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8003 (http) with context path '/api'
2022-02-22 11:38:33.541 INFO 32008 --- [ main] com.company.name.UploadApplication : Started UploadApplication in 4.794 seconds (JVM running for 5.374)
^C
# 文件信息记录下,我们待会儿恢复后方便对比
[root@Aspirant file_system]# ll
总用量 28268
-rwxr-xr-- 1 root root 28941538 2月 22 11:20 a.jar
-rw-r--r-- 1 root root 2207 2月 22 11:38 log.txt
# 删除程序和日志
[root@Aspirant file_system]# rm a.jar log.txt
rm:是否删除普通文件 "a.jar"?y
rm:是否删除普通文件 "log.txt"?y
# 看看是不是真的删除了
[root@Aspirant file_system]# ll
总用量 0
演示恢复
# 到此,我们开始恢复刚刚删除但还在运行的程序和文件,由我们刚刚查询到的进程id去查看进程的文件使用情况,可以看到我们之前删除的两个文件后面已经被标记删除(deleted)
[root@Aspirant file_system]# lsof -g 32008|grep /home/file_system
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 32008 32008 root cwd DIR 253,1 4096 794984 /home/file_system
java 32008 32008 root DEL REG 253,1 789089 /home/file_system/a.jar
java 32008 32008 root 1w REG 253,1 2207 789088 /home/file_system/log.txt (deleted)
java 32008 32008 root 2w REG 253,1 2207 789088 /home/file_system/log.txt (deleted)
java 32008 32008 root 4r REG 253,1 28941538 789089 /home/file_system/a.jar (deleted)
java 32008 32008 root 5r REG 253,1 28941538 789089 /home/file_system/a.jar (deleted)
# 将运行中的Java程序cp到指定位置
[root@Aspirant file_system]# cp /proc/32008/fd/4 /home/file_system/a.jar
# 如果是文本文件,还可以直接通过cat或者tail进行查看
[root@Aspirant file_system]# cat /proc/32008/fd/2
nohup: 忽略输入
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.0)
2022-02-22 11:38:29.456 INFO 32008 --- [ main] com.company.name.UploadApplication : Starting UploadApplication v1.0 using Java 1.8.0_211 on Aspirant with PID 32008 (/home/file_system/a.jar started by root in /home/file_system)
2022-02-22 11:38:29.464 INFO 32008 --- [ main] com.company.name.UploadApplication : The following profiles are active: dev
2022-02-22 11:38:31.565 INFO 32008 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8003 (http)
2022-02-22 11:38:31.583 INFO 32008 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-02-22 11:38:31.583 INFO 32008 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.39]
2022-02-22 11:38:31.664 INFO 32008 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/api] : Initializing Spring embedded WebApplicationContext
2022-02-22 11:38:31.664 INFO 32008 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2127 ms
_ _ |_ _ _|_. ___ _ | _
| | |\/|_)(_| | |_\ |_)||_|_\
/ |
3.3.2
2022-02-22 11:38:33.024 INFO 32008 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2022-02-22 11:38:33.451 INFO 32008 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator'
2022-02-22 11:38:33.515 INFO 32008 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8003 (http) with context path '/api'
2022-02-22 11:38:33.541 INFO 32008 --- [ main] com.company.name.UploadApplication : Started UploadApplication in 4.794 seconds (JVM running for 5.374)
# 查看Java程序是否恢复成功
[root@Aspirant file_system]# ls
a.jar
# 再恢复下日志文件
[root@Aspirant file_system]# cp /proc/32008/fd/2 /home/file_system/log.txt
# 看看是否恢复成功,与之前记录的进行对比一下文件信息
[root@Aspirant file_system]# ll
总用量 28268
-rwxr-xr-- 1 root root 28941538 2月 22 11:45 a.jar
-rw-r--r-- 1 root root 2207 2月 22 11:47 log.txt
恢复方法
-
方法一(使用lsof命令)
-
首先检查一下你的Linux是否有此命令,如果没有则如下安装,已有则跳过
yum -y install lsof
-
查看指定进程id的文件使用情况
lsof -g [GID]
lsof输出各列信息的意义如下:
- COMMAND:进程的名称 PID:进程标识符
- USER: 进程所有者
- FD: 文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
- TYPE: 文件类型,如DIR、REG等
- DEVICE: 指定磁盘的名称
- SIZE: 文件的大小
- NODE: 索引节点(文件在磁盘上的标识)
- NAME: 打开文件的确切名称
FD 列中的文件描述符cwd 值表示应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改,txt 类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序。其次数值表示应用程序的文件描述符,这是打开该文件时返回的一个整数。如上的最后一行文件/dev/initctl,其文件描述符为 10。u 表示该文件被打开并处于读取/写入模式,而不是只读 ® 或只写 (w) 模式。同时还有大写 的W 表示该应用程序具有对整个文件的写锁。该文件描述符用于确保每次只能打开一个应用程序实例。初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的 FD 都是从 3 开始。
-
根据这些信息来恢复文件或程序
# 拷贝到指定位置path cp /proc/[GID]/fd/[FD列前面的数值] [path]
-
-
方法二(通过系统解析的文件)
-
直接进入文件夹,你就会看待很多数字命名的文件,lsof命令也是这样实现的
cd /proc/[GID]/fd
-
然后执行
ll 或者 ls -l
,就可以看到对应文件的映射指向哪里 -
将对应的文件映射指向的文件拷贝到你想要的位置即可
-