我正在尝试使用 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