Linux下用rm误删除文件的三种恢复方法
sinye56 2025-01-05 20:03 12 浏览 0 评论
对于rm,很多人都有惨痛的教训。我也遇到一次,一下午写的程序就被rm掉了,幸好只是一个文件,第二天很快又重新写了一遍。但是很多人可能就不像我这么幸运了。本文收集了一些在Linux下恢复rm删除的文件的方法,给大家作为参考。
1.几点建议避免误删
首先,最好的方法是避免这个问题,以下是几点建议:
1、rm -rf误操作的后果是可怕的,rm -f也要三思而行,不能轻易使用。
2、做好数据备份。
3、用一些策略避免出错:
提倡在shell下用 TAB 补全,用脚本执行任务,减少出错的机会。或者编写一个脚本,起名rm,在脚本里将真实的rm改为mv ,将删除的都mv到一个指定的目录里面,定期清理。
那么rm删除的文件还能恢复吗?
rm的man里面有如下说法:
请注意,如果使用 rm 来删除文件,通常仍可以将该文件恢复原状。如果想保证该文件的内容无法还原,请考虑使用 shred。
所以理论上rm删除的文件是还能恢复的。删掉文件其实只是将指向数据块的索引点(information nodes)释放,只要不被覆盖,数据其实还在硬盘上,关键在于找出索引点,然后将其所指数据块内的数据抓出,再保存到另外的分区。在用rm误删除文件后,我们要做的第一件事就是保证不再向误删文件的分区写数据。
2.使用lsof命令恢复
lsof命令用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户执行。
在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。
1.语法
lsof(选项)
2.参数
-a:列出打开文件存在的进程;
-c<进程名>:列出指定进程所打开的文件;
-g:列出GID号进程详情;
-d<文件号>:列出占用该文件号的进程;
+d<目录>:列出目录下被打开的文件;
+D<目录>:递归列出目录下被打开的文件;
-n<目录>:列出使用NFS的文件;
-i<条件>:列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号>:列出指定进程号所打开的文件;
-u:列出UID号进程详情;
-h:显示帮助信息;
-v:显示版本信息。
3.使用
查看
lsof -i:(端口) 查看这个端口有那些进程在访问,比如22端口
shell> lsof -i:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1939 root 3u IPv4 12317 0t0 TCP *:ssh (LISTEN)
sshd 1939 root 4u IPv6 12321 0t0 TCP *:ssh (LISTEN)
sshd 2790 root 3u IPv4 15229 0t0 TCP 192.168.178.128:ssh->192.168.178.1:64601 (ESTABLISHED)
sshd 2824 root 3u IPv4 15528 0t0 TCP 192.168.178.128:ssh->192.168.178.1:64673 (ESTABLISHED)
sshd 2990 root 3u IPv4 15984 0t0 TCP 192.168.178.128:ssh->192.168.178.1:64686 (ESTABLISHED)
sshd 14695 root 3u IPv4 39558 0t0 TCP 192.168.178.128:ssh->192.168.178.1:49662 (ESTABLISHED)
lsof输出各列信息的意义如下:
- COMMAND:进程的名称
- PID:进程标识符
- USER:进程所有者
- FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
- TYPE:文件类型,如DIR、REG等
- DEVICE:指定磁盘的名称
- SIZE:文件的大小
- NODE:索引节点(文件在磁盘上的标识)
- NAME:打开文件的确切名称
恢复文件
利用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
再次提醒,恢复前提是这个进程必须存在。
3.使用extundelete工具
extundelete工具安装
- extundelete下载地址:http://extundelete.sourceforge.net/
wget https://nchc.dl.sourceforge.net/project/extundelete/extundelete/0.2.4/extundelete-0.2.4.tar.bz2
解压该文件tar jxvf extundelete-0.2.4.tar.bz2
若报这种错误
[root@docking ~]# tar jxvf extundelete-0.2.4.tar.bz2
tar (child): bzip2:无法 exec: 没有那个文件或目录
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
则使用yum -y install bzip2进行解决
[root@docking ~]# tar jxvf extundelete-0.2.4.tar.bz2
extundelete-0.2.4/
extundelete-0.2.4/acinclude.m4
extundelete-0.2.4/missing
extundelete-0.2.4/autogen.sh
extundelete-0.2.4/aclocal.m4
extundelete-0.2.4/configure
extundelete-0.2.4/LICENSE
extundelete-0.2.4/README
...................................................
cd extundelete-0.2.4
./configure
若这步骤报错
[root@docking extundelete-0.2.4]# ./configure
Configuring extundelete 0.2.4
configure: error: in `/root/extundelete-0.2.4':
configure: error: C++ compiler cannot create executables
See `config.log' for more details
则使用yum -y install gcc-c++解决.
若执行上一步仍然报错,
[root@docking extundelete-0.2.4]# ./configure
Configuring extundelete 0.2.4
configure: error: Can't find ext2fs library
则使用yum -y install e2fsprogs e2fsprogs-devel来解决。
#Ubuntu的解决办法为sudo apt-get install e2fslibs-dev e2fslibs-dev
不出意外的话到这里应该configure能够顺利完成.
[root@docking extundelete-0.2.4]# ./configure
Configuring extundelete 0.2.4
Writing generated files to disk
[root@docking extundelete-0.2.4]#
最后make然后 make install
[root@docking extundelete-0.2.4]# make
make -s all-recursive
Making all in src
extundelete.cc: 在函数‘ext2_ino_t find_inode(ext2_filsys, ext2_filsys, ext2_inode*, std::string, int)’中:
extundelete.cc:1272:29: 警告:在 {} 内将‘search_flags’从‘int’转换为较窄的类型‘ext2_ino_t {aka unsigned int}’ [-Wnarrowing]
buf, match_name2, priv, 0};
^
[root@docking extundelete-0.2.4]# make install
Making install in src
/usr/bin/install -c extundelete '/usr/local/bin'
extundelete安装完成.
扫描误删除的文件:
使用df -lh查看挂载:
taroballs@taroballs-PC:~$ df -lh
文件系统 容量 已用 可用 已用% 挂载点
udev 1.9G 0 1.9G 0% /dev
tmpfs 387M 1.8M 385M 1% /run
/dev/sda2 92G 61G 26G 71% /
tmpfs 1.9G 49M 1.9G 3% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sda3 104G 56G 44G 57% /home
tmpfs 387M 40K 387M 1% /run/user/1000
/dev/sda4 70G 20G 47G 30% /media/taroballs/d8423f8c-d687-4c03-a7c8-06a7fb57f96d
/dev/sdb1 6.8G 4.1G 2.8G 60% /media/taroballs/taroballs
/dev/sr0 4.0G 4.0G 0 100% /media/taroballs/2018-01-16-12-36-00-00
taroballs@taroballs-PC:~$ cd /media/taroballs/taroballs/
taroballs@taroballs-PC:/media/taroballs/taroballs$
可以看到,我们的目录/media/taroballs/taroballs
挂载到/dev/sdb1 这个文件系统中.
umount我们的挂载盘
比如:
taroballs@taroballs-PC:~$ df -lh | grep /dev/sdb1
/dev/sdb1 6.8G 4.1G 2.8G 60% /media/taroballs/taroballs
umount这个目录
taroballs@taroballs-PC:~$ umount /media/taroballs/taroballs
taroballs@taroballs-PC:~$ df -lh | grep /dev/sdb1
taroballs@taroballs-PC:~$
#记得删除一定要后umount哦,不然二次写入谁也帮不了你呢。
通过inode节点恢复
taroballs@taroballs-PC:~$ mkdir recovertest
taroballs@taroballs-PC:~$ cd recovertest/
taroballs@taroballs-PC:~/recovertest$
执行恢复extundelete /dev/sdb1 --inode 2
taroballs@taroballs-PC:/media/taroballs/taroballs$ sudo extundelete /dev/sdb1 --inode 2
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 8 groups loaded.
Group: 0
Contents of inode 2:
.
.省略N行
File name | Inode number | Deleted status
. 2
.. 2
deletetest 12 Deleted
tmppasswd 14 Deleted
通过扫描发现了我们删除的文件夹,现在执行恢复操作。
(1)恢复单一文件tmppasswd
taroballs@taroballs-PC:~/recovertest$ extundelete /dev/sdb1 --restore-file passwd
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 8 groups loaded.
Loading journal descriptors ... 46 descriptors loaded.
Successfully restored file tmppasswd
恢复文件是放到了当前目录RECOVERED_FILES。
查看恢复的文件:
taroballs@taroballs-PC:~/recovertest$ cat tmppasswd
tcpdump:x:172:72::/:/sbin/nologin
(2)恢复目录deletetest
extundelete /dev/sdb1 --restore-directory deletetest
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 8 groups loaded.
Loading journal descriptors ... 46 descriptors loaded.
Searching for recoverable inodes in directory deletetest ...
5 recoverable inodes found.
Looking through the directory structure for deleted files ...
(3)恢复所有
taroballs@taroballs-PC:~/recovertest$ extundelete /dev/sdb1 --restore-all
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 8 groups loaded.
Loading journal descriptors ... 46 descriptors loaded.
Searching for recoverable inodes in directory / ...
5 recoverable inodes found.
Looking through the directory structure for deleted files ...
0 recoverable inodes still lost.
taroballs@taroballs-PC:~/recovertest$ tree
backuptest/
├── deletetest
│ └── innerfolder
│ └── deletefile.txt
└── tmppasswd
2 directories, 2 files
(4)恢复指定inode
taroballs@taroballs-PC:~/recovertest$ extundelete /dev/sdb1 --restore-inode 14
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 8 groups loaded.
Loading journal descriptors ... 46 descriptors loaded.
taroballs@taroballs-PC:~/recovertest$ cat file.14
tcpdump:x:172:72::/:/sbin/nologin
#注意恢复inode的时候,恢复 出来的文件名和之前不一样,需要单独进行改名。
最后附上extundelete的用法:
$ extundelete --help
Usage: extundelete [options] [--] device-file
Options:
--version, -[vV] Print version and exit successfully.
--help, Print this help and exit successfully.
--superblock Print contents of superblock in addition to the rest.
If no action is specified then this option is implied.
--journal Show content of journal.
--after dtime Only process entries deleted on or after 'dtime'.
--before dtime Only process entries deleted before 'dtime'.
Actions:
--inode ino Show info on inode 'ino'.
--block blk Show info on block 'blk'.
--restore-inode ino[,ino,...]
Restore the file(s) with known inode number 'ino'.
The restored files are created in ./RECOVERED_FILES
with their inode number as extension (ie, file.12345).
--restore-file 'path' Will restore file 'path'. 'path' is relative to root
of the partition and does not start with a '/'
The restored file is created in the current
directory as 'RECOVERED_FILES/path'.
--restore-files 'path' Will restore files which are listed in the file 'path'.
Each filename should be in the same format as an option
to --restore-file, and there should be one per line.
--restore-directory 'path'
Will restore directory 'path'. 'path' is relative to the
root directory of the file system. The restored
directory is created in the output directory as 'path'.
--restore-all Attempts to restore everything.
-j journal Reads an external journal from the named file.
-b blocknumber Uses the backup superblock at blocknumber when opening
the file system.
-B blocksize Uses blocksize as the block size when opening the file
system. The number should be the number of bytes.
--log 0 Make the program silent.
--log filename Logs all messages to filename.
--log D1=0,D2=filename Custom control of log messages with comma-separated
Examples below: list of options. Dn must be one of info, warn, or
--log info,error error. Omission of the '=name' results in messages
--log warn=0 with the specified level to be logged to the console.
--log error=filename If the parameter is '=0', logging for the specified
level will be turned off. If the parameter is
'=filename', messages with that level will be written
to filename.
-o directory Save the recovered files to the named directory.
The restored files are created in a directory
named 'RECOVERED_FILES/' by default.
- 上一篇:Linux扩容/目录
- 下一篇:Linux 虚拟机的共享文件夹使用
相关推荐
- 程序员:JDK的安装与配置(完整版)_jdk的安装方法
-
对于Java程序员来说,jdk是必不陌生的一个词。但怎么安装配置jdk,对新手来说确实头疼的一件事情。我这里以jdk10为例,详细的说明讲解了jdk的安装和配置,如果有不明白的小伙伴可以评论区留言哦下...
- Linux中安装jdk并配置环境变量_linux jdk安装教程及环境变量配置
-
一、通过连接工具登录到Linux(我这里使用的Centos7.6版本)服务器连接工具有很多我就不一一介绍了今天使用比较常用的XShell工具登录成功如下:二、上传jdk安装包到Linux服务器jdk...
- 麒麟系统安装JAVA JDK教程_麒麟系统配置jdk
-
检查检查系统是否自带java在麒麟系统桌面空白处,右键“在终端打开”,打开shell对话框输入:java–version查看是否自带java及版本如图所示,系统自带OpenJDK,要先卸载自带JDK...
- 学习笔记-Linux JDK - 安装&配置
-
前提条件#检查是否存在JDKrpm-qa|grepjava#删除现存JDKyum-yremovejava*安装OracleJDK不分系统#进入安装文件目...
- Linux新手入门系列:Linux下jdk安装配置
-
本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...
- 测试员必备:Linux下安装JDK 1.8你必须知道的那些事
-
1.简介在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还得一个一个的摸索尝试,而且网上大多数都是一些Oracle收购Sun前,或者就...
- Linux 下安装JDK17_linux 安装jdk1.8 yum
-
一、安装环境操作系统:JDK版本:17二、安装步骤第一步:下载安装包下载Linux环境下的jdk1.8,请去官网(https://www.oracle.com/java/technologies/do...
- 在Ubuntu系统中安装JDK 17并配置环境变量教程
-
在Ubuntu系统上安装JDK17并配置环境变量是Java开发环境搭建的重要步骤。JDK17是Oracle提供的长期支持版本,广泛用于开发Java应用程序。以下是详细的步骤,帮助你在Ubuntu系...
- 如何在 Linux 上安装 Java_linux安装java的步骤
-
在桌面上拥抱Java应用程序,然后在所有桌面上运行它们。--SethKenlon(作者)无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序...
- Windows和Linux环境下的JDK安装教程
-
JavaDevelopmentKit(简称JDK),是Java开发的核心工具包,提供了Java应用程序的编译、运行和开发所需的各类工具和类库。它包括了JRE(JavaRuntimeEnviro...
- linux安装jdk_linux安装jdk软连接
-
JDK是啥就不用多介绍了哈,外行的人也不会进来看我的博文。依然记得读大学那会,第一次实验课就是在机房安装jdk,编写HelloWorld程序。时光飞逝啊,一下过了十多年了,挣了不少钱,买了跑车,娶了富...
- linux安装jdk,全局配置,不同用户不同jdk
-
jdk1.8安装包链接:https://pan.baidu.com/s/14qBrh6ZpLK04QS8ogCepwg提取码:09zs上传文件解压tar-zxvfjdk-8u152-linux-...
- 运维大神教你在linux下安装jdk8_linux安装jdk1.7
-
1.到官网下载适合自己机器的版本。楼主下载的是jdk-8u66-linux-i586.tar.gzhttp://www.oracle.com/technetwork/java/javase/downl...
- window和linux安装JDK1.8_linux 安装jdk1.8.tar
-
Windows安装JDK1.8的步骤:步骤1:下载JDK打开浏览器,找到JDK下载页面https://d.injdk.cn/download/oraclejdk/8在页面中找到并点击“下载...
- 最全的linux下安装JavaJDK的教程(图文详解)不会安装你来打我?
-
默认已经有了linux服务器,且有root账号首先检查一下是否已经安装过java的jdk任意位置输入命令:whichjava像我这个已经安装过了,就会提示在哪个位置,你的肯定是找不到。一般我们在...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)