Apacheによって開かれたままになっている削除されたファイルを回復しますか?


10

Apacheログファイルが削除されたが、Apacheによって開いたままになっているとします。次に、これは私がやっていることです:

pid=$(lsof | grep text.txt | awk '/deleted/ {print $2}')
fd=$(lsof | grep text.txt | awk '/deleted/ {print $4}' | grep -oE "[[:digit:]]{1,}")

cp /proc/$pid/fd/$fd directorytobecopied/testfile.txt

これは私がファイルを回復して元の場所に戻すために行っていることです。上記のコードは見栄えが悪いので、これを行う簡単な方法はありますか?さらに、ファイルが削除された場所(directorytobecopied)からどのようにして知ることができるので、手動でファイルの元の場所を誰かに尋ねて、そこに戻す必要がありません。


lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'
Rahul Patil

回答:


14

ファイルが削除されたがまだ開いている場合、そのファイルはファイルシステムにまだ存在しますが(inodeがあります)、ハードリンクカウントは0です。ファイルへのリンクがないため、名前で開くことはできません。 。iノードでファイルを開く機能もありません。

そのファイルシステムを介してファイルを発見する方法はありません。特に、最後にあったディレクトリでファイルを探す方法はありません。ディレクトリエントリがなくなっています。残っているのはファイル自体だけです。ファイルシステムデバッガーを使用してファイルにアクセスできますが、これにはroot権限が必要であり、使用が難しく、エラーが発生しやすくなります。

Linuxは、特別なシンボリックリンクを介して開いているファイルを公開します/proc。これらのリンクは呼び出されます/proc/12345/fd/42。12345はプロセスのPID、42はそのプロセスのファイル記述子の番号です。そのプロセスと同じユーザーとして実行されているプログラムはファイルにアクセスできます(読み取り/書き込み/実行権限は、ファイルが削除されたときと同じです)。

ファイルを開いたときの名前は、シンボリックリンクのターゲットに引き続き表示されます。ファイルがの場合、リンク/var/log/apache/foo.logのターゲットは/var/log/apache/foo.log (deleted)です。(ファイルが開かれた後に名前が変更された場合、シンボリックリンクのターゲットは名前の変更を反映する場合があります。)

したがって、次のように、開いているプロセスのPIDと開いている記述子を指定すると、開いている削除済みファイルの内容を回復できます。

recover_open_deleted_file () {
  old_name=$(readlink "$1")
  case "$old_name" in
    *' (deleted)')
      old_name=${old_name%' (deleted)'}
      if [ -e "$old_name" ]; then
        new_name=$(TMPDIR=${old_name%/*} mktemp)
        echo "$oldname has been replaced, recovering content to $new_name"
      else
        new_name="$old_name"
      fi
      cat <"$1" >"$new_name";;
    *) echo "File is not deleted, doing nothing";;
  esac
}
recover_open_deleted_file "/proc/$pid/fd/$fd"

プロセスIDだけがわかっていて記述子がわからない場合は、次のコマンドですべてのファイルを復元できます。

for x in /proc/$pid/fd/*; do
  recover_open_deleted_file "$x"
done

プロセスIDもわからない場合は、すべてのプロセスを検索できます。

for x in /proc/[1-9]*/fd/*; do
  case $(readlink "$x") in
    /var/log/apache/*) recover_open_deleted_file "$x";;
  esac
done

このリストは、の出力を解析して取得することもできますがlsof、単純でも信頼性も移植性も高くありません(これはとにかくLinux固有です)。


/ proc / x / fd / yは、xが読み取りまたは書き込み用に開いているかどうかに関係なく、読み取りまたは書き込み用に開くことができます。
ステファンChazelas

unix OSが開いているときにファイルの削除を許可するのはなぜですか。Windowsでは実行できませんが、説明はありますか
munish

@munish Windowsは協調マルチタスクモデルから始まりました。アプリケーションが正常に動作しない場合、システムがダウンする可能性があります。ほとんどの問題は今では修正されていますが、Windowsはアプリケーションによるファイルのハイジャックを許可しています。ファイルが開いている限り、ファイルの名前を変更したり削除したりすることはできません。Unixではこれを許可していません。ファイルの削除や名前の変更は、ファイルを開くこととは関係ありません。
Gilles「SO-悪をやめなさい」

1
ミューズの対称性の起源を私のために保存しました!1000回以上ありがとうございます!
dotancohen 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.