作为一个多用户、多任务的操作系统,Linux 下的文件一旦被删除,是难以恢复的。尽管删除命令只是在文件节点中作删除标记,并不真正清除文件内容,但是其他用户和一些有写盘动作的进程会很快覆盖这些数据。不过,对于家庭单机使用的Linux ,或者误删文件后及时补救,还是可以恢复的。 # J* \7 G% F: Z- _. O% O9 p
1 、Ext2文件系统结构的简单介绍3 j4 I( p6 l& r) K! X% `; |& `% H
在Linux 所用的Ext2文件系统中,文件是以块为单位存储的,默认情况下每个块的大小是1K,不同的块以块号区分。每个文件还有一个节点,节点中包含有文件所有者,读写权限,文件类型等信息。对于一个小于12个块的文件,在节点中直接存储文件数据块的块号。如果文件大于12个块,那么节点在12个块号之后存储一个间接块的块号,在这个间接块号所对应的块中,存储有256 个文件数据块的块号(Ext2fs中每个块号占用4 字节,这样一个块中所能存储的块号就是1024/4=256)。如果有更大的文件,那么还会在节点中出现二级间接块和三级间接块。
/ Q, Q1 d$ ]' L( m8 v& H$ T 2 、恢复被误删文件的方法3 a& r- d4 [/ z
大多数Linux 发行版都提供一个debugfs 工具,可以用来对Ext2文件系统进行编辑操作。不过在使用这个工具之前,还有一些工作要做。4 y7 T8 i2 V( w9 K- J" b$ q- f, \! I
首先以只读方式重新挂载被误删的文件所在分区。使用如下命令:(假设文件在/usr分区)3 Z; f( Q( a9 Z* W, x( ]
mount –r –n –o remount /usr -r 表示只读方式挂载;-n表示不写入/etc/mtab,如果是恢复/etc上的文件,就加上这个参数。如果系统说xxx partion busy,可以用fuser 命令查看一下是哪些进程使用这个分区上的文件:( E* ]: r7 i; d
fuser –v –m /usr9 g$ m' A+ b6 q/ g: m2 Z+ _
如果没有什么重要的进程,用以下命令停掉它们:; L3 [, v- g+ e2 K* [" _
fuser -k–v –m /usr
7 R5 ]0 k! V) y6 g 然后就可以重新挂载这些文件系统了。
& Y8 V2 s+ i- U f 如果是把所有的文件统一安装在一个大的/ 分区当中,可以在boot提示符下用linux single进入单用户模式,尽量减少系统进程向硬盘写入数据的机会,要不干脆把硬盘挂在别的机器上。另外,恢复出来的数据不要写到/ 上面,避免破坏那些有用的数据。如果机器上有dos/windows ,可以写到这些分区上面:
7 S0 q& K8 Z- T$ P mount –r –n /dev/hda1 /mnt/had
2 l' r9 H- |$ k" V! G 然后就可以执行debugfs :(假设Linux 在 /dev/hda5)
$ q/ F: I+ F' s. j #debugfs /dev/hda5. ?* ]( A: `5 J# j- M, u2 l6 ]
就会出现debugfs 提示符debugfs :
5 N) }0 @3 b( T+ U% V( } 使用lsdel 命令可以列出很多被删除的文件的信息:
! w# U- }) C$ M# e debugfs :lsdel
' `7 ~+ @; D& D7 ^ debugfs : 2692 deleted inodes found.2 Q4 c3 X+ m2 ?/ o
Inode Owner Mode Size Blocks Time deleted1 A7 A$ D ?& Y; L- G! x( e
164821 0 100600 8192 1/ 1 Sun May 13 19 :22:46 2001
1 f; N$ R: _1 O) q …………………………………………………………
! G% a4 b+ @$ w$ [ 36137 0 100644 4 1/ 1 Tue Apr 24 10 :11:15 2001
7 \+ X! S: p. T h x 196829 0 100644 149500 38/ 38 Mon May 27 13 :52:04 2001
8 l* t2 Y0 ^' o8 v3 ]7 F! }7 n debugfs :* d; p$ R w# X/ i3 K% j" A7 o+ g6 o
列出的文件有很多(这里找到2692个),第一字段是文件节点号,第二字段是文件所有者,第三字段是读写权限,接下来是文件大小,占用块数,删除时间。% O% i& U2 C9 U" k9 w
然后就可以根据文件大小和删除日期判断那些是我们需要的。比如我们要恢复节点是196829的文件: 可以先看看文件数据状态:
/ m) R7 A9 e. E. S) y debugfs :stat
) F# l* k1 I: e0 ?$ G2 O Inode : 196829 Type: regular Mode : 0644 Flags : 0x0 Version:1
) n( p! y; ^% D( O* Z: j6 H* A+ t0 h4 k User: 0 Group: 0 Size : 149500; n* B& y# B- a& s/ Y- e4 k
File ACL: 0 Directory ACL: 0. N5 R3 L0 c f
Links : 0 Blockcount : 38
3 I+ l8 Q4 Y/ N& R$ s Fragment: Address: 0 Number : 0 Size : 0
: r1 w; Y' |' u ctime : 0x31a9a574 —— Mon May 27 13:52:04 20019 z! W$ p! M3 @, X }6 B# b
atime : 0x31a21dd1 —— Tue May 21 20:47:29 2001
% `! K' V% }# j mtime : 0x313bf4d7 —— Tue Mar 5 08 :01:27 20012 q* ^) }8 |0 q$ Q( Y
dtime : 0x31a9a574 —— Mon May 27 13:52:04 2001
* X) V* l9 i3 r. ? BLOCKS:
{8 b7 H4 V3 \ 594810 594811 594814 594815 594816 594817 …………………………………。. F2 L9 C) k+ w$ u9 O
TOTAL : 38
0 E- O# m- c3 Y. P- K( T6 \, j 然后就可以用dump指令恢复文件:
5 P& U; s/ V- |) ^ debugfs :dump /mnt/hda/01.sav; Y% P% L6 q" D. f
这样就把文件恢复出来了。退出debugfs :1 \2 h) J4 [' C3 R0 o! u/ @7 J7 Z
debugfs :quit
Y4 {7 a, x5 G. Y7 X U- W 另一种方法是手工编辑inode :0 ^ k1 c. q% s' ]
debugfs :mi 0 W- U% E" {7 P8 A3 T
Mode [0100644]5 w6 [9 i* F3 w- @2 X$ `6 x
User ID [0]
6 N/ M1 H1 z8 U Group ID [0]" ~4 D# L7 F. S# e9 f
Size [149500]+ m! y; ]! X# X: k5 |5 z
Creation time [0x31a9a574]
H% q" M9 o( s- A( y Modification time [0x31a9a574]
3 [( S* D: |2 m Access time [0x31a21dd1]8 E6 g* a( U O0 \: p, X: x
Deletion time [0x31a9a574] 0% y( J( {, c) _& d7 W7 ^ a' C
Link count [0] 1 Block count [38]# Q S* {- ~- e* Z% ^
File flags [0x0]- q* U/ o3 n8 i" }+ h+ \1 v( o
Reserved1 [0]
6 L% t! G% e1 _, o$ ] File acl [0]) Y2 Z5 I+ v F( ]" P. h0 \/ v
Directory acl [0]
: |# u2 r+ q" | Fragment address [0]/ t) i* X- o% z4 o! R0 _
Fragment number [0]3 `, `5 t/ |, t: P- M7 V/ m
Fragment size [0]
; B1 G8 _) L2 [, c& \ y% y Direct Block #0 [594810]
7 u$ b' P' e A ……………………………。
- v) Z% S1 B! R5 }' B7 m7 X Triple Indirect Block [0]0 S: h- s: V9 ]* q2 R$ }) F; Q7 t3 U! ]
使用mi指令后每次显示一行信息以供编辑,其它行可以直接按回车表示确认,把deletion time 改成0 (未删除),Link count改成1.改好后退出debugfs :3 K" ~7 z; ]% _. I& s7 N
debugfs :quit( P; S9 k, l& \
然后用fsck检查/dev/hda5& {4 K: ~! ?$ f2 g
fsck /dev/hda5
8 W3 @# a# F: G8 ` 程序会说找到丢失的数据块,放在lost+found里面。这个目录里的文件就是我们要的东东。 |