I got my config files in /etc folder all messed up because I did not take care of shell expansion while doing rsync:rsync --progress --delete -avhHe ssh /etc/logrotate.d/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} root@my.ipaddress:/etcI think the problem is that the '.' following logrotate got expanded and subsequently some folders such as /etc/httpd got deleted.I want to learn from this mistake by doing it correctly. How do I prevent shell expansion when rsync multiple files with ssh?
rsync --delete deleted most files in the destination directory, why?
rsync
That command boils down to this:rsync --delete --recursive /etc/logrotate.d/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} root@my.ipaddress:/etcThe . in there has its literal meaning - it's part of the name - so that isn't the problem. The part in {} is subject to brace expansion: each comma-separated part gets expanded and concatenated to the part of that argument that came before (/etc/logrotate.d/). (It'd also get anything after, if there were anything: a{BC}d expands to aBd aCd).So this command is equivalent torsync --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 root@my.ipaddress:/etcor to pick just one directory out so it's short:rsync --delete --recursive /etc/logrotate.d/httpd root@my.ipaddress:/etcrsync interprets the from location as a single entity, and if it doesn't end with a / it makes a new file or directory with just the last part of that name inside the given destination path: here, that's httpd. So this makes a /etc/httpd on the destination and copies the contents of /etc/logrotate.d/httpd into it.With --delete, it will then delete everything that wasn't in /etc/logrotate.d/httpd on the source. The problem since /etc/logrotate.d/httpd probably doesn't exist at all, copying it and deleting any files that weren't present on the source means deleting everything in all of those directories. If it did exist, its contents won't be the same as /etc/httpd, so (almost) everything will be deleted.So the problem is just that you have the logrotate.d part there at all, when you really meant to copy the same directories under /etc. What you probably meant was just:rsync --progress --delete -avhHe ssh /etc/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} root@my.ipaddress:/etcThat copies /etc/httpd and its contents to /etc/httpd on the destination, and so on. If you meant to copy things inside logrotate.d, put that in the path on both sides.One thing you may find useful is the -n or --dry-run option to rsync:-n, --dry-run               perform a trial run with no changes madeThat will show you a preview of what would happen, but not actually make any changes on either end. You can use that to check it's what you want before running the real thing.You asked how to prevent shell expansion in the arguments you gave to rsync. As above, I don't think that's actually what you want given the problem you had, but if you do ever need to: brace expansions don't take place inside quotes, so a{BC}d stays as a{BC}d literally.