Linux下用rm誤刪除文件的三種恢復方法

来源:https://www.cnblogs.com/cs-markdown10086/archive/2022/11/30/16938664.html
-Advertisement-
Play Games

Linux下用rm誤刪除文件的三種恢復方法 對於rm,很多人都有慘痛的教訓。我也遇到一次,一下午寫的程式就被rm掉了,幸好只是一個文件,第二天很快又重新寫了一遍。但是很多人可能就不像我這麼幸運了。本文收集了一些在Linux下恢復rm刪除的文件的方法,給大家作為參考。 1.幾點建議避免誤刪 首先,最好 ...


Linux下用rm誤刪除文件的三種恢復方法

 對於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 ([email protected]) (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 ([email protected]) (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工具安裝

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.

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前面介紹了對稱加密演算法,本文將介紹密碼學中另一類重要應用:消息摘要(Digest),什麼是消息摘要?簡單的定義是:對一份數據,進行一個單向的Hash函數,生成一個固定長度的Hash值,這個值就是這份數據的摘要,也稱為指紋。 ...
  • 下麵給出 Kafka 一些重要概念,讓大家對 Kafka 有個整體的認識和感知,後面還會詳細的解析每一個概念的作用以及更深入的原理 • Producer:消息生產者,向 Kafka Broker 發消息的客戶端。 • Consumer:消息消費者,從 Kafka Broker 取消息的客戶端。 • ...
  • 虛基類/抽象類 抽象類:有純虛函數的類 虛繼承 通過修飾繼承方式, 如代碼2是虛繼承,被虛繼承的類稱為虛基類 虛繼承派生類的記憶體佈局方式 先是vbptr => 派生類的數據 =>基類的數據 , 對比代碼1和代碼2,發現原本基類數據在前面,派生類數據在後面,但是在虛繼承的時候 基類數據方式放到了後面, ...
  • ULID:Universally Unique Lexicographically Sortable Identifier(通用唯一詞典分類標識符) UUID:Universally Unique Identifier(通用唯一標識符) 為什麼不選擇UUID UUID 目前有 5 個版本: 版本1: ...
  • 1、環境搭建 1.1 依賴 <!-- nacos註冊中心 註解 @EnableDiscoveryClient --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba- ...
  • 經常看到有群友調侃“為什麼搞Java的總在學習JVM調優?那是因為Java爛!我們.NET就不需要搞這些!”真的是這樣嗎?今天我就用一個案例來分析一下。 昨天,一位學生問了我一個問題:他建了一個預設的ASP.NET Core Web API的項目,也就是那個WeatherForecast的預設項目模 ...
  • 用acme.sh自動部署功能變數名稱證書 安裝ACME 目前使用量最大的免費SSL證書就是Let’s Encrypt,自2018-03開始,Let’s Encrypt官方發佈上線了免費的SSL泛功能變數名稱證書,目前通過DNS方式獲取比較快,國內可以通過鵝雲的DNSPod功能變數名稱API或者貓雲功能變數名稱API自動簽發Let’ ...
  • public static void GetRegistData() { string name = "huishuangzhu"; //搜索到註冊表根目錄 RegistryKey hkml = Registry.ClassesRoot; //搜索到註冊表根目錄下的XXX文件夾。 RegistryK ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...