天天看點

Linux檔案誤删除,如何快速恢複

事件還原

最近伺服器的磁盤不夠用了,通過

df -lh

指令,發現其他挂載盤有相對充裕的磁盤空間,就想着将服務放在另外的磁盤目錄,然後通過軟連結使原本目錄正常通路;具體場景如下:

[[email protected] boci_logs]# df -lh
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/myvg-root
                      259G  218G   28G  89% /
tmpfs                  63G   36G   28G  58% /dev/shm
           

上述目錄

/dev/mapper/myvg-root

之前是近100%的使用率,後面将某一目錄進行遷移,以及軟連結建立的操作:

mv /home/xxx /dev/shm/xxx
ln -s /dev/shm/xxx /home/xxx
ln -s /dev/shm/xxx /home/xxx-2
           

此時我發現

/home/xxx-2

目錄多餘了,就想删掉,執行了指令:

rm -rf /home/xxx-2
           

可想而知,反應過來的時候,多奔潰,平白無故給自己加工作量;

恢複方法

先看看檔案是不是還有程序占用(檔案恢複也基于此種情形)

[[email protected] boci_logs]# lsof | grep /dev/shm
java      132387      root  mem       REG               0,16       48602  474577519 /dev/shm/xxx/lib/tomcat-juli-8.5.27.jar
java      132387      root  mem       REG               0,16      148604  474577516 /dev/shm/xxx/lib/tomcat-jdbc-8.5.51.jar
java      132387      root  mem       REG               0,16      144971  474577512 /dev/shm/xxx/lib/tomcat-jdbc-8.5.27.jar
java      132387      root  mem       REG               0,16      260325  474577509 /dev/shm/xxx/lib/tomcat-embed-websocket-8.5.51.jar
java      132387      root  mem       REG               0,16      257229  474577506 /dev/shm/xxx/lib/tomcat-embed-websocket-8.5.27.jar
java      132387      root  mem       REG               0,16      250194  474577503 /dev/shm/xxx/lib/tomcat-embed-el-8.5.51.jar
java      132387      root  mem       REG               0,16      240316  474577500 /dev/shm/xxx/lib/tomcat-embed-el-8.5.27.jar
java      132387      root  mem       REG               0,16     3241499  474577494 /dev/shm/xxx/lib/tomcat-embed-core-8.5.51.jar
java      132387      root  mem       REG               0,16     3107599  474577491 /dev/shm/xxx/lib/tomcat-embed-core-8.5.27.jar
java      132387      root  mem       REG               0,16       12373  474577488 /dev/shm/xxx/lib/tomcat-annotations-api-8.5.51.jar
           

發現部分檔案還存在程序,pid為 132387。根據pid進入此目錄

cd /proc/132387/fd

檢視檔案:

[[email protected] fd]# ll
總用量 0
lr-x------ 1 root root 64 11月 27 16:00 10 -> /dev/shm/xxx/lib/asm-analysis-4.1.jar
lr-x------ 1 root root 64 11月 27 16:00 100 -> /dev/shm/xxx/lib/spring-aop-4.3.14.RELEASE.jar
lr-x------ 1 root root 64 11月 27 16:00 101 -> /dev/shm/xxx/lib/spring-aspects-4.3.14.RELEASE.jar
lr-x------ 1 root root 64 11月 27 16:00 102 -> /dev/shm/xxx/lib/spring-beans-4.3.14.RELEASE.jar
lr-x------ 1 root root 64 11月 27 16:00 103 -> /dev/shm/xxx/lib/spring-boot-1.5.10.RELEASE.jar
lr-x------ 1 root root 64 11月 27 16:00 104 -> /dev/shm/xxx/lib/spring-boot-autoconfigure-1.5.10.RELEASE.jar
lr-x------ 1 root root 64 11月 27 16:00 105 -> /dev/shm/xxx/lib/spring-boot-starter-1.5.10.RELEASE.jar
lr-x------ 1 root root 64 11月 27 16:00 106 -> /dev/shm/xxx/lib/spring-boot-starter-aop-1.5.10.RELEASE.jar
lr-x------ 1 root root 64 11月 27 16:00 107 -> /dev/shm/xxx/lib/spring-boot-starter-cache-1.5.10.RELEASE.jar
           

上述我截取了一部分資料,實際上,你會找到非常多的資料,你還需要過濾篩選。另外,手動恢複的時候需要每個目錄一層層恢複,下面以恢複

/dev/shm/xxx/

目錄為例。先建立該目錄:

mkdir -vp /dev/shm/xxx/

。然後在

/proc/pid/fd

目錄下篩選出該目錄下可恢複檔案:

[[email protected] fd]# ll | grep /dev/shm/xxx/ | awk '{print $9, $11}'
1 /dev/shm/xxx/logs/stdout.log
10 /dev/shm/xxx/lib/asm-analysis-4.1.jar
100 /dev/shm/xxx/lib/spring-aop-4.3.14.RELEASE.jar
101 /dev/shm/xxx/lib/spring-aspects-4.3.14.RELEASE.jar
102 /dev/shm/xxx/lib/spring-beans-4.3.14.RELEASE.jar
103 /dev/shm/xxx/lib/spring-boot-1.5.10.RELEASE.jar
104 /dev/shm/xxx/lib/spring-boot-autoconfigure-1.5.10.RELEASE.jar
105 /dev/shm/xxx/lib/spring-boot-starter-1.5.10.RELEASE.jar
106 /dev/shm/xxx/lib/spring-boot-starter-aop-1.5.10.RELEASE.jar
107 /dev/shm/xxx/lib/spring-boot-starter-cache-1.5.10.RELEASE.jar
108 /dev/shm/xxx/lib/spring-boot-starter-data-jpa-1.5.10.RELEASE.jar
109 /dev/shm/xxx/lib/spring-boot-starter-data-redis-1.5.10.RELEASE.jar
11 /dev/shm/xxx/lib/asm-tree-4.1.jar
           

awk '{print $9, $11}'

指令是将

ll | grep /dev/shm/xxx/

的輸出項的第9個字段與第11個字段提取出來。第9個字段稱之為:檔案id,第11個字段稱之為:檔案路徑,則恢複指令為:

cp 檔案id 檔案路徑

。經處理,上述輸出結果最終執行的恢複指令為(可用正則替換,查找目标:(^\d+), 替換為:cp $1):

cp 1 /dev/shm/xxx/logs/stdout.log
cp 10 /dev/shm/xxx/lib/asm-analysis-4.1.jar
cp 100 /dev/shm/xxx/lib/spring-aop-4.3.14.RELEASE.jar
cp 101 /dev/shm/xxx/lib/spring-aspects-4.3.14.RELEASE.jar
cp 102 /dev/shm/xxx/lib/spring-beans-4.3.14.RELEASE.jar
cp 103 /dev/shm/xxx/lib/spring-boot-1.5.10.RELEASE.jar
cp 104 /dev/shm/xxx/lib/spring-boot-autoconfigure-1.5.10.RELEASE.jar
cp 105 /dev/shm/xxx/lib/spring-boot-starter-1.5.10.RELEASE.jar
cp 106 /dev/shm/xxx/lib/spring-boot-starter-aop-1.5.10.RELEASE.jar
cp 107 /dev/shm/xxx/lib/spring-boot-starter-cache-1.5.10.RELEASE.jar
cp 108 /dev/shm/xxx/lib/spring-boot-starter-data-jpa-1.5.10.RELEASE.jar
cp 109 /dev/shm/xxx/lib/spring-boot-starter-data-redis-1.5.10.RELEASE.jar
cp 11 /dev/shm/xxx/lib/asm-tree-4.1.jar
           

上述指令,在/proc/pid/fd 目錄下,執行即可。

題外話

雖然已經能夠簡單地檔案恢複,但是還需要注意兩點:

1.一個目錄源最好不要有多個軟連結,很容易誤操作删除本不想删除的檔案;

2.要删除軟連結時,執行

unlink xxx

,xxx為連結目錄/檔案

繼續閱讀