rsync --delete удалил большинство файлов в целевом каталоге. Почему?

rsync --delete удалил большинство файлов в целевом каталоге. Почему?

У меня все файлы конфигурации в /etcпапке испортились, потому что я не позаботился о расширении оболочки при выполнении rsync:

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

Я думаю, проблема в том, что «.» после logrotate был расширен, и впоследствии некоторые папки, такие как, /etc/httpdбыли удалены.

Я хочу извлечь урок из этой ошибки, сделав ее правильно. Как предотвратить расширение оболочки при rsync нескольких файлов с ssh?

решение1

Эта команда сводится к следующему:

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

В .этом месте in имеет буквальное значение - это часть имени - так что это не проблема. Часть in {}подлежитрасширение скобки: каждая часть, разделенная запятыми, расширяется и объединяется с частью аргумента, которая была до ( /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 интерпретирует местоположение «откуда» как единое целое, и если ононе делаетзаканчивается на , /он создает новый файл или каталог только с последней частью этого имени внутри указанного пути назначения: здесь это httpd. Таким образом, это создает в месте назначения и копирует в него /etc/httpdсодержимое ./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 выполнить пробный запуск без внесения изменений

Это покажет вам предварительный просмотр того, что произойдет, но не внесет никаких фактических изменений ни на одном из концов. Вы можете использовать это, чтобы проверить, что это то, что вы хотите, перед тем, как запустить реальную вещь.


Вы спрашивали, как предотвратить расширение оболочки в аргументах, которые вы дали rsync. Как и выше, я не думаю, что это на самом деле то, что вы хотите, учитывая вашу проблему, но если вам когда-нибудь понадобится: расширение фигурных скобок не происходит внутри кавычек, поэтому "a{BC}d"остается как a{BC}dесть.

Связанный контент