将变量中存储的空格分隔的参数传递给命令

将变量中存储的空格分隔的参数传递给命令

我从互联网上劫持了一个非常简洁的备份脚本,但是在某个地方发生了类似的事情

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 变量都是大写的。最好将所有其他变量名称保留为小写,以避免覆盖重要的内容。

相关内容