Apache에서 연 삭제된 파일을 복구하시겠습니까?

Apache에서 연 삭제된 파일을 복구하시겠습니까?

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

파일을 복원해서 원래 위치로 되돌리려고 하는 작업입니다. 위의 코드가 보기에 좋지 않기 때문에 이 작업을 수행하는 더 쉬운 방법이 있습니까? 또한 파일이 삭제된 위치를 어떻게 알 수 있습니까(복사할 디렉터리) 그러면 파일이 원래 어디에 있었는지 수동으로 물어보고 다시 넣을 필요가 없습니다.

답변1

파일이 삭제되었지만 여전히 열려 있는 경우 해당 파일이 파일 시스템에 여전히 존재한다는 의미입니다.인덱스 노드) 하지만 하나 있어요하드 링크개수는 0입니다. 파일에 대한 링크가 없으므로 이름으로 열 수 없습니다. inode를 통해 파일을 여는 도구도 없습니다.

파일 시스템을 통해, 특히 파일이 마지막으로 발견된 디렉터리에서 파일을 검색할 수 없습니다. 디렉토리 항목이 사라집니다. 남은 것은 파일 자체뿐입니다. 파일 시스템 디버거를 사용하여 이 파일에 액세스할 수 있지만 루트 권한이 필요하고 사용하기 어렵고 오류가 발생하기 쉽습니다.

Linux는 특별한 기호 링크를 통해 열린 파일을 노출합니다 /proc. 이러한 링크는 /proc/12345/fd/4212345가 프로세스의 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에만 해당됩니다).

관련 정보