Linux

確定文件是否正在被寫入?

  • April 18, 2020

我需要部署一個在特定目錄中查找 tar 文件的自動化程序(通過 1 分鐘 cron 腳本)。如果找到 tar 文件,則將其解壓縮到適當的位置,然後刪除該 tar 文件。

tar 文件通過 SSH 從另一台伺服器自動複製到該伺服器。在某些情況下,tar 文件非常大,包含很多文件。

我期望遇到的問題:如果將 tar 文件複製到伺服器需要超過 1 分鐘,並且 cron 腳本每分鐘執行一次,它將看到 .tar.gz 文件並嘗試執行解壓它,即使 tar 文件仍在寫入過程中。

有什麼方法(通過 bash 命令)來測試目前是否正在寫入文件,或者它是否只是部分文件等?

我正在考慮的一種替代方法是將文件複製為不同的文件副檔名(如.tar.gz.part),然後.tar.gz在傳輸完成後重命名為。但是我想我會嘗試弄清楚是否有一種方法可以首先在命令行中確定文件是否完整……有什麼線索嗎?

您在正確的軌道上,重命名文件是一個原子操作,因此在上傳後執行重命名簡單、優雅且不易出錯。我能想到的另一種方法是用於lsof | grep filename.tar.gz檢查文件是否正在被另一個程序訪問。

最好的辦法是使用lsof來確定文件是否已被任何程序打開:

#  lsof -f -- /var/log/syslog
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
rsyslogd 1520 syslog    1w   REG  252,2    72692 16719 /var/log/syslog

你不能輕易判斷它是否正在被寫入,但如果它正在被寫入,它必須是打開的。


編輯:讓我們在這裡解決實際問題,而不是嘗試實施建議的解決方案!

使用 rsync 傳輸文件:

○ → rsync -e ssh remote:big.tar.gz .

這樣,文件不會被複製到現有文件之上,而是複製到臨時文件 ( .big.tar.gz.XXXXXX) 中,直到傳輸完成,然後移動到位。

引用自:https://serverfault.com/questions/415596