在 Linux 使用 rm 删除文件后,恢复起来还是有点麻烦的,不像 windows 上还有回收站和各种文件恢复软件;而且在删除文件,后执行了大量的 IO 操作,恢复起来更是困难,甚至无法恢复。

rm 删除的本质是执行unlink() 函数,删除目录是执行 remove() 函数;而 unlink() 函数主要做的就是删除文件目录项并减少一个连接数,如果链接数为0并且没有任何进程打开该文件,文件将会被删除,但是其 inode 节点信息和data bloack仍然存在,只是解除了链接。如果是最后一个连接但是有进程打开文件,文件仍会存在,直到打开的文件被关闭。

关于 inode表、super block、inode节点、data block不在此赘叙。

rm 的防护措施:

alias rm='rm -i'
###强制删除确认,应写到配置文件中去
alias rm='mv -f $@ ~/backup'
###将rm 换成 mv,每隔一段时间清理 backup文件夹

文件恢复操作:
删除的文件正在被运行的进程使用(I/O操作): lsof

[free@hurd]$ cat file
total 240
drwxrwxr-x 2 free free   4096 Sep 13 11:20 asciiquarium_1.1
-rw-rw-r-- 1 free free  15436 Mar  9  2013 asciiquarium.tar.gz
drwxrwxr-x 5 free free   4096 Apr 25 16:36 bumblebee-Old-and-abbandoned
drwxrwxr-x 2 free free   4096 Apr 23 16:01 cmatrix-1.2a
-rw-r--r-- 1 root root  74376 Apr 23 15:35 cmatrix-1.2a.tar.gz
drwxr-xr-x 3 free free   4096 Sep 30 10:08 extundelete-0.2.4
-rw-rw-r-- 1 free free 108472 Jan  4  2013 extundelete-0.2.4.tar.bz2
-rw-rw-r-- 1 free free      0 Sep 30 11:35 file
drwxrwxr-x 3 free free   4096 Sep 30 10:21 recovertest
-rw-rw-r-- 1 free free  18785 Dec 17  2006 Term-Animation-2.4.tar.gz
[free@hurd]$ cat >> file
test rm file

重新开启一个终端:

[free@hurd]$ cat file
total 240
drwxrwxr-x 2 free free   4096 Sep 13 11:20 asciiquarium_1.1
-rw-rw-r-- 1 free free  15436 Mar  9  2013 asciiquarium.tar.gz
drwxrwxr-x 5 free free   4096 Apr 25 16:36 bumblebee-Old-and-abbandoned
drwxrwxr-x 2 free free   4096 Apr 23 16:01 cmatrix-1.2a
-rw-r--r-- 1 root root  74376 Apr 23 15:35 cmatrix-1.2a.tar.gz
drwxr-xr-x 3 free free   4096 Sep 30 10:08 extundelete-0.2.4
-rw-rw-r-- 1 free free 108472 Jan  4  2013 extundelete-0.2.4.tar.bz2
-rw-rw-r-- 1 free free      0 Sep 30 11:35 file
drwxrwxr-x 3 free free   4096 Sep 30 10:21 recovertest
-rw-rw-r-- 1 free free  18785 Dec 17  2006 Term-Animation-2.4.tar.gz
test rm file
###可以看到新增的内容
###然后删除文件
[free@hurd]$ rm file
[free@hurd]$ sudo lsof | grep cat
cat       23877          free  cwd       DIR              253,1      4096     131380 /home/free/tmp
cat       23877          free  rtd       DIR              253,1      4096          2 /
cat       23877          free  txt       REG              253,1     54080     658390 /usr/bin/cat
cat       23877          free  mem       REG              253,1 106070960     677352 /usr/lib/locale/locale-archive
cat       23877          free  mem       REG              253,1   2173512     657095 /usr/lib64/libc-2.17.so
cat       23877          free  mem       REG              253,1    164240     657088 /usr/lib64/ld-2.17.so
cat       23877          free    0u      CHR              136,4       0t0          7 /dev/pts/4
cat       23877          free    1w      REG              253,1       639     132886 /home/free/tmp/file (deleted)
cat       23877          free    2u      CHR              136,4       0t0          7 /dev/pts/4
###看到(deleted)了,找到其pid,进入/proc/pid/fd/
[free@hurd]$ cd /proc/23877/fd
[free@hurd]$ ls -l
total 0
lrwx------ 1 free free 64 Sep 30 11:40 0 -> /dev/pts/4
l-wx------ 1 free free 64 Sep 30 11:40 1 -> /home/free/tmp/file (deleted)
lrwx------ 1 free free 64 Sep 30 11:40 2 -> /dev/pts/4
###文件描述符1就是被删除的文件
###将其复制即可
[free@hurd]$ cp 1 /tmp/file.rec 
[free@hurd]$ cat /tmp/file.rec 
total 240
drwxrwxr-x 2 free free   4096 Sep 13 11:20 asciiquarium_1.1
-rw-rw-r-- 1 free free  15436 Mar  9  2013 asciiquarium.tar.gz
drwxrwxr-x 5 free free   4096 Apr 25 16:36 bumblebee-Old-and-abbandoned
drwxrwxr-x 2 free free   4096 Apr 23 16:01 cmatrix-1.2a
-rw-r--r-- 1 root root  74376 Apr 23 15:35 cmatrix-1.2a.tar.gz
drwxr-xr-x 3 free free   4096 Sep 30 10:08 extundelete-0.2.4
-rw-rw-r-- 1 free free 108472 Jan  4  2013 extundelete-0.2.4.tar.bz2
-rw-rw-r-- 1 free free      0 Sep 30 11:35 file
drwxrwxr-x 3 free free   4096 Sep 30 10:21 recovertest
-rw-rw-r-- 1 free free  18785 Dec 17  2006 Term-Animation-2.4.tar.gz
test rm file
###恢复成功

删除的文件正在没有被任何进程使用:extundelete

恢复数据之前停止对当前分区做任何I/O操作,防止inode被覆盖

在此只是进行简单的操作,并没有使用dd对当前分区进行备份和使用 umount 分区

安装extundelete

[free@hurd]$ wget https://nchc.dl.sourceforge.net/project/extundelete/extundelete/0.2.4/extundelete-0.2.4.tar.bz2
[free@hurd]$ sudo yum -y install gcc-c++  bzip2
[free@hurd]$ sudo yum -y install e2fsprogs e2fsprogs-devel
[free@hurd]$ 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
extundelete-0.2.4/install-sh
extundelete-0.2.4/config.h.in
extundelete-0.2.4/src/
extundelete-0.2.4/src/extundelete.cc
extundelete-0.2.4/src/block.h
extundelete-0.2.4/src/kernel-jbd.h
extundelete-0.2.4/src/insertionops.cc
extundelete-0.2.4/src/block.c
extundelete-0.2.4/src/cli.cc
extundelete-0.2.4/src/extundelete-priv.h
extundelete-0.2.4/src/extundelete.h
extundelete-0.2.4/src/jfs_compat.h
extundelete-0.2.4/src/Makefile.in
extundelete-0.2.4/src/Makefile.am
extundelete-0.2.4/configure.ac
extundelete-0.2.4/depcomp
extundelete-0.2.4/Makefile.in
extundelete-0.2.4/Makefile.am
[free@hurd]$ cd extundelete-0.2.4/
[free@hurd]$ ./configure 
Configuring extundelete 0.2.4
Writing generated files to disk
[free@hurd]$ make
make -s all-recursive
Making all in src
extundelete.cc: In function ‘ext2_ino_t find_inode(ext2_filsys, ext2_filsys, ext2_inode*, std::string, int)’:
extundelete.cc:1272:29: warning: narrowing conversion of ‘search_flags’ from ‘int’ to ‘ext2_ino_t {aka unsigned int}’ inside { } [-Wnarrowing]
    buf, match_name2, priv, 0};
                             ^
                             
[free@hurd]$ sudo make install
Making install in src
  /usr/bin/install -c extundelete '/usr/local/bin'

###安装完成
###查看文件系统和挂载
[free@hurd]$ df -lh
Filesystem     Type     1K-blocks    Used Available Use% Mounted on
/dev/vda1      ext4      41151808 5292972  33745404  14% /
devtmpfs       devtmpfs    497112       0    497112   0% /dev
tmpfs          tmpfs       507704       0    507704   0% /dev/shm
tmpfs          tmpfs       507704     428    507276   1% /run
tmpfs          tmpfs       507704       0    507704   0% /sys/fs/cgroup
tmpfs          tmpfs       101544       0    101544   0% /run/user/1001
###挂载在根目录下,文件系统是/dev/vda1
[free@hurd]$ mkdir recovertest
[free@hurd]$ cd recovertest
###创建目录以作恢复测试使用
###删除文件测试
[free@hurd]$ rm /home/free/file
###直接恢复所有文件
[free@hurd]$ sudo /usr/local/bin/extundelete /dev/vda1 --restore-all
NOTICE: Extended attributes are not restored.
WARNING: EXT3_FEATURE_INCOMPAT_RECOVER is set.
The partition should be unmounted to undelete any files without further data loss.
If the partition is not currently mounted, this message indicates 
it was improperly unmounted, and you should run fsck before continuing.
If you decide to continue, extundelete may overwrite some of the deleted
files and make recovering those files impossible.  You should unmount the
file system and check it with fsck before using extundelete.
Would you like to continue? (y/n) 
y
Loading filesystem metadata ... 320 groups loaded.
Loading journal descriptors ... 29380 descriptors loaded.
Searching for recoverable inodes in directory / ... 
22 recoverable inodes found.
Looking through the directory structure for deleted files ... 
Unable to restore inode 266403 (var/lib/yum/transaction-done.2018-09-30.13:02.11): Space has been reallocated.
Unable to restore inode 266331 (var/lib/rsyslog/imjournal.state.tmp): Space has been reallocated.
Unable to restore inode 266320 (var/lib/ntp/drift.TEMP): Space has been reallocated.
Unable to restore inode 266319 (var/cache/yum/x86_64/7/base/repomd.xml.old.tmp): Space has been reallocated.
Unable to restore inode 266374 (var/cache/yum/x86_64/7/base/repomdGvOHrztmp.xml): Space has been reallocated.
Unable to restore inode 266325 (var/cache/yum/x86_64/7/epel/repomd.xml.old.tmp): Space has been reallocated.
Unable to restore inode 266326 (var/cache/yum/x86_64/7/extras/repomd.xml.old.tmp): Space has been reallocated.
Unable to restore inode 266328 (var/cache/yum/x86_64/7/updates/repomd.xml.old.tmp): Space has been reallocated.
Unable to restore inode 266327 (var/cache/yum/x86_64/7/gf/repomd.xml.old.tmp): Space has been reallocated.
8 recoverable inodes still lost.
Unable to restore inode 266323 (file.266323): Space has been reallocated.
Unable to restore inode 266324 (file.266324): Space has been reallocated.
Unable to restore inode 266334 (file.266334): Space has been reallocated.
Unable to restore inode 266371 (file.266371): Space has been reallocated.
Unable to restore inode 266372 (file.266372): Space has been reallocated.
Unable to restore inode 266386 (file.266386): Space has been reallocated.
Unable to restore inode 660679 (file.660679): Space has been reallocated.
Unable to restore inode 674046 (file.674046): Space has been reallocated.
[free@hurd]$  cd RECOVERED_FILES/
###恢复的文件都在 RECOVERED_FILES/目录下
[free@hurd]$ ls
home  lost+found  tmp  var
[free@hurd]$ ls home/free
tmp
###此处可以看到我们恢复失败了
###此方法失败也很正常,因为各种 I/O可能会操作覆盖文件的inode信息
###但也是有可能成功恢复文件的
###extundelete的用法
[free@hurd]$  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.