rsync --delete 刪除了目標目錄中的大部分文件,為什麼?

rsync --delete 刪除了目標目錄中的大部分文件,為什麼?

我的/etc資料夾中的設定檔全部搞亂了,因為我在執行 rsync 時沒有處理 shell 擴充:

rsync --progress --delete -avhHe ssh /etc/logrotate.d/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc

我認為問題在於“.”以下 logrotate 被擴展,隨後一些資料夾(例如/etc/httpd被刪除)。

我想透過正確的做法從這個錯誤中學習。使用 ssh rsync 多個檔案時如何防止 shell 擴充?

答案1

該命令歸結為:

rsync --delete --recursive /etc/logrotate.d/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc

那裡.有它的字面意思 - 它是名稱的一部分 - 所以這不是問題。中的部分{}大括號擴展:每個逗號分隔的部分都會擴展並連接到該參數之前的部分 ( /etc/logrotate.d/)。 (如果有的話,它也會得到任何東西:a{BC}d擴展到aBd aCd)。

所以這個命令相當於

rsync --delete --recursive /etc/logrotate.d/httpd /etc/logrotate.d/mariadb /etc/logrotate.d/php-fpm /etc/logrotate.d/ppp /etc/logrotate.d/wpa_supplicant /etc/logrotate.d/yum [email protected]:/etc

或只選擇一個目錄,這樣它就很短:

rsync --delete --recursive /etc/logrotate.d/httpd [email protected]:/etc

rsync 將「來自」位置解釋為單一實體,如果它以 a 結尾,/它會建立一個新檔案或目錄,其中僅包含給定目標路徑中該名稱的最後一部分:這裡,即httpd.因此,這會/etc/httpd在目標上創建 a 並將其內容複製/etc/logrotate.d/httpd到其中。

有了--delete,那麼它就會刪除所有內容不是/etc/logrotate.d/httpd源上。問題 - 由於/etc/logrotate.d/httpd可能根本不存在,因此複製它並刪除來源中不存在的任何檔案意味著刪除所有這些目錄中的所有內容。如果它確實存在,它的內容將與 不同/etc/httpd,因此(幾乎)所有內容都將被刪除。

所以問題在於logrotate.d,當您真正打算將相同的目錄複製到/etc.你的意思可能只是:

rsync --progress --delete -avhHe ssh /etc/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc

/etc/httpd其內容複製到/etc/httpd目的地,依此類推。如果您打算複製裡面的內容logrotate.d,請將其放在兩側的路徑中。

您可能會發現有用的一件事是-n--dry-run選項rsync

-n, --dry-run 執行試運行而不進行任何更改

這將向您展示將要發生的情況的預覽,但實際上不會在兩端進行任何更改。在運行真正的東西之前,您可以使用它來檢查它是否是您想要的。


您詢問如何在您提供的參數中防止 shell 擴展rsync。如上所述,考慮到您遇到的問題,我認為這實際上並不是您想要的,但如果您確實需要:大括號擴展不會發生在引號內,因此"a{BC}d"保持a{BC}d字面意思。

相關內容