我有一個腳本,它總是在我將其重定向到文件的位置提供輸出,我想做的是旋轉重定向的文件,下面是我啟動腳本並重定向它的位置:
.
somecode
.
su - username -c "command >> /path/to/directory/output.txt" &
.
.
code continues..
以下是我正在嘗試建立的 crontab:
cd /path/to/directory/
timestamp=`date "+%Y%m%d"`
mv ./output.txt ./logs/output.txt_$timestamp
touch output.txt
chmod 757 ./output.txt
gzip ./logs/output.txt_$timestamp
find ./logs/output.txt* -type f -mtime +2 | xargs rm
或者這個也未能完成這項工作:
timestamp=`date "+%Y%m%d"`
cp ./output.txt ./logs/output.txt_$timestamp
echo "" > ./output.txt
gzip ./logs/output.txt_$timestamp
在第一個程式碼中,原始腳本失敗並且不再工作,在第二個腳本中,它不會清理output.txt 檔案。
有沒有辦法在保持腳本運行的同時做到這一點?筆記;我正在運行 Unix Solaris。
提前致謝。
答案1
這通常是透過添加一個來完成的嘆息重新啟動命令的處理程序在其他一些命令(通常logrotate
)移動文件之後。在 *nix 作業系統上,您可以在寫入檔案時移動檔案(我相信,但需要注意的是,它必須仍然位於同一檔案系統上);額外的行將附加到新位置的文件中。
答案2
您確實無法更改正在運行的進程的重定向stdout
和/或stderr
新檔案(請參閱下面的註釋)(這是使用重定向stdout
或stderr
作為長時間運行的進程的日誌檔案的原因之一壞的主意。
當進程啟動時,命令的重定向元素由啟動進程的 shell 執行。如有必要,目標檔案會以適當的模式(追加或覆蓋)開啟和創建,並且可能根據重定向模式截斷為零位元組。然後打開的檔案描述符被傳遞給子進程。從字面上看,該開啟的檔案描述符是子進程擁有的指向重定向檔案的唯一連結。這是文件的連結。
這是重要的一點 - 作為直接到文件的鏈接,打開描述符與文件的目錄條目 - “文件名”相同。更改該名稱甚至刪除該目錄條目(例如使用rm
命令)對進程中開啟的檔案描述符絕對沒有影響。
@l0b0 的答案是正確的,需要輪換日誌的進程傾向於使用SIGHUP
處理程序來執行此類輪換,但在重定向輸出的情況下「輪換日誌」並不是那麼簡單 - 新的輸出檔案的名稱是什麼?子進程不知道它的“名稱”是什麼stdout
和/或是stderr
什麼 - 並且輸出“檔案”甚至可能不是檔案。
日誌輪替方案必須是設計的到流程中 - 日誌記錄應該以這樣的方式集成,例如,日誌條目不會在旋轉日誌檔案的過程中遺失。
(好吧,可以是可能的更改正在運行的進程的stdout
/stderr
流 - 但這是必須的 - 再次 -設計的進入這個過程。這不是開箱即用的二進位文件,bash
如果您向它發送SIGHUP
...)
答案3
非常感謝大家的回复,找不到辦法做到這一點,因此作為解決方法,我設置了 crontab 來停止原始腳本,進行輪換並在非高峰時再次啟動。