命令的执行方式与终端或 Bash 脚本不同

命令的执行方式与终端或 Bash 脚本不同

我正在尝试使用 attic 自动执行备份脚本,但我遇到了这个问题:实际的 attic 命令在从脚本执行和直接在终端中执行时的执行方式不同。

该脚本构建并执行以下命令:

/usr/bin/attic create --stats --verbose --exclude '/home/.cache' /media/attic-backup/paolo.attic::2016-08-27 /home

该命令输出从 attic 备份的文件:

/home
/home/.attic
/home/.attic/keys
/home/.cache
/home/git
/home/git/.bash_history
etc etc

/home/.cache应该跳过该目录...

但是,如果我从终端执行相同的命令,我会得到:

$ /usr/bin/attic create --stats --verbose --exclude '/home/.cache' /media/attic-backup/paolo.attic::2016-08-27 /home
/home
/home/.attic
/home/.attic/keys
/home/git
/home/git/.bash_history
etc etc

现在该/home/.cache目录已被跳过。

这不是 sudo 的问题。

为什么脚本中的命令表现不同?

答案1

当您说脚本“构建”命令时,您的意思是它将其存储在字符串(变量)中,然后尝试将该字符串作为命令执行吗?如果是这样,将引号放在字符串 ( '/home/.cache') 内不会产生您期望的效果,因为引号被视为数据并作为参数的一部分传递给命令,而不是在作为参数传递之前被解析和删除。本质上,这意味着 rsync 被告知要排除,'/home/.cache'而不仅仅是/home/.cache。请参阅BashFAQ #50:我尝试将命令放入变量中,但复杂的情况总是失败!了解更多信息。

如果你尝试逐个构建命令,通常最好的方法是使用数组。如下所示:

atticcmd=(/usr/bin/attic create --stats --verbose --exclude '/home/.cache' /media/attic-backup/paolo.attic::2016-08-27 /home)
"${atticcmd[@]}"

或者你也可以在数组中只构建其中的一部分:

atticopts=(--stats --verbose)
for e in "${excludes[@]}"; do
    atticopts+=(--exclude "$e")
done
/usr/bin/attic create "${atticopts[@]}" /media/attic-backup/paolo.attic::2016-08-27 /home

相关内容