파일이 삭제되었지만 여전히 열려있는 경우 파일이 파일 시스템에 여전히 존재 하지만 ( inode가 있음 ) 하드 링크 수는 0입니다. 파일에 대한 링크가 없으므로 이름으로 열 수 없습니다. . inode로 파일을 여는 기능도 없습니다.
파일 시스템을 통해 파일을 발견 할 수있는 방법이 없으며, 특히 마지막 디렉토리에서 파일을 찾을 수 없습니다. 디렉토리 항목이 사라졌습니다. 남아있는 것은 파일 자체입니다. 파일 시스템 디버거를 사용하여 파일에 접근 할 수 있지만 루트 권한이 필요하고 사용하기 어렵고 오류가 발생하기 쉽습니다.
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에만 해당).
lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'