Linux
在刪除所有文件之前,可以在 bash 腳本中完成 rm 命令嗎?
我編寫了一個簡單的 bash 腳本,每天將某些文件備份到備份掛載並保留最近 3 天的備份。這顯然太簡單了,因為我偶爾會遇到奇怪的行為,這可以通過在 rm 完成之前執行第一個 mv 來解釋。
這是腳本:
#!/bin/bash mount /mnt/backups while [ ! -d /mnt/backups/dailyBackup-0 ] do echo "Backup mount not present, sleeping..." sleep 30 done rm -r /mnt/backups/dailyBackup-2 mv /mnt/backups/dailyBackup-1 /mnt/backups/dailyBackup-2 mv /mnt/backups/dailyBackup-0 /mnt/backups/dailyBackup-1 dirname="/mnt/backups/dailyBackup-0" mkdir $dirname cd / rsync -qr --stats root etc var $dirname umount /mnt/backups
雖然這在很多時候都很好,但我有時會得到以下結果,看起來 dailyBackup-1 在dailyBackup-2 完成刪除之前就被移動了。如果這是正在發生的事情,那麼最好的預防方法是什麼?
/mnt/backups/dailyBackup-0: total 0 drwxrwxrwx 1 root root 0 2010-12-07 03:27 var drwxrwxrwx 1 root root 0 2010-12-07 02:39 root drwxrwxrwx 1 root root 0 2010-12-07 02:38 etc /mnt/backups/dailyBackup-1: total 0 drwxrwxrwx 1 root root 0 2010-12-06 03:26 var drwxrwxrwx 1 root root 0 2010-12-06 02:32 root drwxrwxrwx 1 root root 0 2010-12-06 02:32 etc /mnt/backups/dailyBackup-2: total 0 drwxrwxrwx 1 root root 0 2010-12-07 02:36 var drwxrwxrwx 1 root root 0 2010-12-05 03:21 dailyBackup-1
問題很可能是 rm失敗,請注意 var 在 dailyBackup-2 中仍然存在,很可能是因為其中的某些文件無法刪除。
作為關於編寫系統管理 shellscripts 的一般說明:
a)始終確保檢查腳本的(錯誤)輸出,除非您的電子郵件設置損壞,否則您將通過 cronjobs 的郵件自動接收它
b) 始終確保您處理可能發生的任何和所有錯誤(例如,rm 或 mv 失敗)最好將 set -e 放在腳本之上,這將使 shell 在遇到第一個未處理的情況時退出錯誤(為了調試,還要添加 set -x,它將列印所有正在執行的命令,這樣你就可以看到腳本在做什麼)
並回答你原來的問題: rm 在刪除所有文件之前永遠不會退出,或者更準確地說,在它找到的最後一個文件的 unlink() 系統呼叫完成之前。(我能想像在取消連結後文件可能仍然存在的唯一情況可能是一些模糊的錯誤網路文件系統……)但 rm 退出並不意味著所有文件都已成功刪除(即使您是 root 並且正在使用 -fr (你甚至沒有使用 -f)),例如,如果文件在 ext* 文件系統上被標記為不可變,或者文件是在 rm 遍歷樹時新創建的。rm 將報告錯誤消息和不成功的返回統計資訊