我从互联网上劫持了一个非常简洁的备份脚本,但是在某个地方发生了类似的事情
DIRS="/home/ /var/www/html /etc"
tar -czf /backup/file.tar.gz "${DIRS}"
这恰好在我的机器上工作正常,但在我的服务器上它似乎认为它是单个路径并告诉我它不存在:
/bin/tar: /home/ /var/www/html /etc: Cannot stat: No such file or directory
/bin/tar: Exiting with failure status due to previous errors
本地tar版本是1.29,服务器版本是1.28
将目录与该变量分开提供 tar 的正确方法是什么?
答案1
只要这是 bash 脚本(甚至是 sh 的大多数版本),您就应该使用数组来传递参数而不是变量:
DIRS=('/home/' '/var/www/html' '/etc')
tar -czf /backup/file.tar.gz "${DIRS[@]}"
如果您愿意,可以写如下(如果数组变大,通常更容易阅读):
DIRS=(
'/home/'
'/var/www/html'
'/etc'
)
在不支持数组的 shell 中,您需要取消引用变量以允许分词(如果可以避免的话不推荐):
DIRS="/home/ /var/www/html /etc"
tar -czf /backup/file.tar.gz $DIRS
当您引用变量来传递这些参数时,它本质上与以下内容相同:
tar -czf /backup/file.tar.gz "/home/ /var/www/html /etc"
但是,当您通过带引号的数组传递它们时,它会更像:
tar -czf /backup/file.tar.gz "/home/" "/var/www/html" "/etc"
通过不带引号的数组或变量传递它们将执行类似于以下内容的操作:
tar -czf /backup/file.tar.gz /home/ /var/www/html /etc
在这个例子中,这不应该是一个问题,但会导致额外的分词和其他类型的扩展,这些扩展可能是不受欢迎的或可能有害的。
答案2
我同意 jesse_b 的观点。如果可能的话使用数组。
dirs="/home/ /var/www/html /etc"
dirs=($dirs)
tar -czf /backup/file.tar.gz "${dirs[@]}"
我只是想补充一点,最好避免 bash 中的所有大写变量。按照惯例,环境变量和内部 shell 变量都是大写的。最好将所有其他变量名称保留为小写,以避免覆盖重要的内容。