tee -a 不重新建立文件

tee -a 不重新建立文件

我在 Raspberry Pi 3 Debian 最新版本上執行以下命令:

cat /dev/ttyUSB0 | tee -a /media/pi/KINGSTON/klima.out | grep -F $ | tee -a /media/pi/KINGSTON/log

該命令運作良好並且執行其應有的操作;但是,當我刪除(手動或透過 CRON)該klima.out檔案時,它不會重新建立。命令繼續運行,日誌檔案繼續附加,但klima.out檔案沒有回傳。 (也沒有緩衝)。我想每週刪除一次,以免讓它超出所有邊界。有什麼建議麼?

答案1

我假設您的管道運行了很長時間,並且您試圖在運行時刪除日誌檔案。

當您刪除檔案時,tee進程仍將其開啟以進行寫入,這表示磁碟空間不會交還給系統。在關閉所有引用該檔案的開啟檔案描述符之前,這種情況不會發生。

只要在刪除之前指派了檔案描述符,就可以寫入已刪除的檔案。

您必須重新啟動管道才能重新建立文件,並允許回收舊(現在無名)日誌檔案所佔用的空間。

為了避免重新啟動管道,您可以選擇截短文件,即將其大小修剪為零而不刪除它。這將允許tee繼續追加到文件而無需重新打開它。

可以完成截斷文件就像 jlliagre 在他的回答中所顯示的那樣,或使用truncate(屬於 GNU coreutils 一部分的非標準實用程式):

truncate -s 0 /media/pi/KINGSTON/klima.out

的手冊truncate有關該實用程式的詳細資訊。

答案2

如果要恢復文件區塊,則需要清空該文件,而不是取消連結:

這種便攜式方式應該適用於大多數 shell:

: > /media/pi/KINGSTON/klima.out

取消連結檔案(即rm)會刪除目錄條目,但只要檔案保持由讀取者或寫入者開啟狀態,就不會影響檔案內容(inode)。

答案3

您不了解系統如何處理文件。

您刪除了檔案條目,但只要程式保留其句柄,該檔案仍然存在。所以 tee 永遠不會收到條目被刪除的通知,而且它仍然會寫入檔案!

由於硬連結(由 ln 指令建立),一個唯一的檔案可以有許多條目。

您可以編寫自己的 tee 版本,在寫入文件的每一行上關閉和打開文件,但它的性能會非常低,因為它會產生如此多的系統呼叫。

這是一個 shell 函數,它將其輸入拆分為多個檔案:

splitSizeInKio=100

splitInput(){
    local PS4='+splitInput+ '
    set -x
    local i=0
    local fname="$1"
    local ii

    while true
    do if [ $i -lt 10 ]
       then ii=0$i
       else ii=$i
       fi
       local outfile="$fname".$ii
       dd of="$outfile" bs=1024 count=$splitSizeInKio
       i=$((i+1))
    done
}

(如果您溢出了多行而不是大小,則可以使用“head”而不是“dd”。)

使用 bash,您可以像這樣使用“進程替換”:

prog1 | tee >( splitInput somefilename ) | prog2

相關內容