我有一個有趣的問題,可能有也可能沒有解決方案,但如果可能的話我很想有一個:
在 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);
}'