削除されたファイルがまだ何らかのプロセスで開かれている場合、どのように回復しますか?


19
$ cat important_file > /dev/null &
[1] 9711
$ rm important_file 
$ killall -STOP cat

[1]+  Stopped                 cat important_file > /tmp/p
$ ls -l /proc/`pidof cat`/fd/
total 0
lrwx------ 1 vi vi 64 May 13 20:32 0 -> /dev/pts/29
l-wx------ 1 vi vi 64 May 13 20:32 1 -> /tmp/p
lrwx------ 1 vi vi 64 May 13 20:32 2 -> /dev/pts/29
lr-x------ 1 vi vi 64 May 13 20:32 3 -> /home/vi/important_file (deleted)

これを回復するにはimportant_file

私は次のようなものを試しました

injcode -m dup2 -ofd=3 -ofilename=/tmp/recovered_file -oflags=O_CREAT $PID_OF_CAT

しかし、それは何もしません。

回答:


11

/ homeがNFSの場合、/ home / viにアクセス/コピーできる.nfsNNNNNNNNNNファイルがあります。homeがローカルファイルシステムの場合、/ proc / PID / fd / 3リンクを介して同じことを実行できるはずです。

cp /proc/PID/fd/3 /tmp/recovered_file

実際にファイルの削除を取り消す場合は、この件に関するブログ記事をご覧ください。


1
わかりました、それで混乱しましたreadlink /proc/13381/fd/3-> "/ home / vi / important_file(削除済み)"そして/home/vi/important_file\ \(deleted\)明らかに存在しません。
Vi。

22

...特定の時間にコピーするよりも(ファイルのコンテンツのその時間のスナップショットのみを収集するよりも)tail -fそのファイルを新しいファイルに「

tail -c +0 -f /proc/PIDofProgram>/fd/# > /new/path/to/file

(tailの慎重なプログラマのおかげで、バイナリ出力でも動作します。)

ランタイム中tail -f、ファイル自体を開いたままにし、元のプログラムが終了したときにファイルがディスクから削除されるのを安全に防ぎます。このように、停止しないtail -fあなたの元のプログラムが終了した直後に- tail'edチェック/new/path/to/fileそれが最初かどうかであるあなたが欲しいもの。そうでない場合(または他の理由で満足できない場合)は、元のファイルを再度コピーできますが、今回すべての書き込みが「Program」およびまだ実行中tail -fの/ proc / PIDoftail / fd /ディレクトリ。


3
/ proc / PIDofProgram> / fd /#へのハードリンクの作成はどうですか?
becko

2
@becko Invalid cross-device link
カミルマシオロウスキ

10

lsofを使用してiノード番号を検索し、debugfsを使用してハードリンクを再作成します。例えば:

# lsof -p 12345 | grep /var/log/messages
syslogd 12345 root    3w   REG                8,3    3000    987654 /var/log/messages (deleted)
# mount | grep var
/dev/sda2 on /var type ext3 (rw)
# debugfs -w /dev/sda2
debugfs: cd log
debugfs: ln <987654> tmp
debugfs: mi tmp
                      Mode    [0100600] 
                   User ID    [0] 
                  Group ID    [0] 
                      Size    [3181271] 
             Creation time    [1375916400] 
         Modification time    [1375916322] 
               Access time    [1375939901]
             Deletion time    [9601027] 0
                Link count    [0] 1
               Block count    [6232] 
                File flags    [0x0] 
...snip...
debugfs:  q
# mv /var/log/tmp /var/log/messages
# ls -al /var/log/messages
-rw------- 0 root root 3301 Aug  8 10:10 /var/log/messages

あなたが文句を言う前に、私は今すぐ手元に削除されたファイルを持っていないので、上のトランスクリプトを偽造しました;-)

mi削除時間とリンクカウントを適切な値(それぞれ0と1)にリセットするために使用していますが、正常に機能しませんls。リンクカウントはでゼロのままです。カーネルがiノードデータをキャッシュしている可能性があると思います。安全のために、おそらくdebugfsを使用した後、できるだけ早くfsckを使用する必要があります。

私の経験では、一時ファイル名を使用してリンクを作成し、適切な名前に変更する必要があります。元のファイル名に直接リンクすると、ディレクトリが破損する可能性があります。YMMV!


実際に正しく機能せず、システムに損傷を与える場合、なぜこれを提案するのですか?これは単なるWiPであり、実稼働環境で実際に試されるべきではないという回答の中に、より鮮明な免責事項が必要だと思います。
cnst 14

3

あなただけcpのファイル、すなわち:

cp /proc/<pid>/fd/<fdno> /new/path/to/file

もちろん、ファイルがまだ変更されている場合は、このアプローチで問題が発生します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.