恢復開啟的文件

恢復開啟的文件

我有一個有趣的問題,可能有也可能沒有解決方案,但如果可能的話我很想有一個:

在 Solaris 上,開啟的日誌檔案已被刪除,該檔案在進程運行時仍會繼續填充,但現在所有其他工具(如 、 等)都無法存取該cat檔案tail

有沒有辦法在一切保持運行的情況下將目錄中的條目恢復到該文件?

答案1

這是可行的,但有一些駭客攻擊和限制(您需要 root 權限)。

首先找到應用程式使用哪個文件描述符寫入日誌文件,然後在先前的日誌文件位置建立符號連結並指向文件 /proc 條目,例如:

ln -s /var/tmp/file.log /proc/12345/fd/3

第一個限制是,如果檔案僅開啟以供進程寫入,則其權限將不允許非特權使用者讀取其內容。但是,root 和具有 file_dac_read 權限的使用者不會受到影響。或者,您可以使用一個流程來複製文件內容,tail就像吉爾斯在他的評論中建議的那樣。例如:

tail -c +1 -f /proc/12345/fd/5 > /var/tmp/file.log

第二個問題是,當進程關閉或退出時,整個檔案內容將會遺失 ( ln -s) 或部分 ( )。tail -c 1 -f

解決方法是使用程式來監視此事件並在實際呼叫 close 之前備份檔案。

完成這項工作的可能工具有 dtrace、truss、mdb 或 dbx。

以下是在 Solaris 10 上使用 dtrace 的概念證明。

#!/bin/ksh
#
# This dtrace script is monitoring a file descriptor for a given process
# and copy its content to the given path when the file is closed.
#

pid=${1:?"$0: Usage: pid fd path"}
fd=${2:?}
path=${3:?}
[[ -f $path ]] && { echo "$path exists"; exit 1; }
dtrace -w -n '
syscall::close:entry
/pid=='$pid' && arg0=='$fd'/
{
        stop();
        system("cp /proc/%d/fd/%d %s",pid,arg0,"'"$path"'");
        system("prun %d",pid);
        exit(0);
}'

相關內容