$ 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
しかし、それは何もしません。
/ homeがNFSの場合、/ home/viにアクセス/コピーできる.nfsNNNNNNNNNNファイルがあります。 homeがローカルファイルシステムの場合、/ proc/PID/fd/3リンクを介して同じことを実行できるはずです。
cp /proc/PID/fd/3 /tmp/recovered_file
実際にファイルの削除を取り消したい場合は、件名について ブログ投稿 をご覧ください。
...所定の時間にコピーする(およびその時間のファイルのコンテンツのスナップショットのみを収集する)よりも、そのファイルを新しいファイルに "tail -f
"するのが適切です。
tail -c +0 -f /proc/PIDofProgram>/fd/# > /new/path/to/file
(尾の用心深いプログラマーのおかげで、それはバイナリ出力でも動作します。)
ランタイム中、tail -f
自体がファイルを開いたままにし、元のプログラムが終了したときにファイルがディスクから削除されないようにします。したがって、元のプログラムが終了した直後にtail -f
を停止しないでください。最初に末尾の/new/path/to/file
をチェックして、それがisかどうかを確認してください。そうでない場合(または他の理由で満足できない場合)、元のファイルを再度コピーできますが、今回はafterへのすべての書き込みが「プログラム」によって実行され、まだ実行中ですtail -f
の/ proc/PIDoftail/fd /ディレクトリ。
Lsofを使用してiノード番号を検索し、debugfsを使用してiノード番号へのハードリンクを再作成します。例えば:
# 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!
あなたは単にファイルをcp
することができます、すなわち:
cp /proc/<pid>/fd/<fdno> /new/path/to/file
もちろん、ファイルがまだ変更されている場合は、この方法で問題が発生します。