我的/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
字面意思。