在rsync参数中使用环境变量(用引号和转义符处理)

时间:2018-07-31 08:49:47

标签: linux bash environment-variables

我想将rsync与看起来像

的--exclude命令一起使用
rsync -av --exclude={"*.ext1","*.ext2", "*.ext3"} source target 

(由于某种原因,使用这种语法比使用--exclude-from = FILE语法更方便)

我想在rsync中使用环境变量,这样我就可以做到

export toto='{"*.ext1","*.ext2", "*.ext3"}'
rsync -av --exclude=$toto source target 

问题在于它无法按我希望的方式工作。当我在$ toto变量上使用自动完成功能时,它会显示:

\{\"\*.ext1\",\"\*.ext2\",\ \"\*.ext3\"\} 

这实际上是rsync理解的,并且完全感到困惑。

有人能解释这种“引号和转义字符”行为背后的原因吗?

2 个答案:

答案 0 :(得分:1)

如果我理解您的问题,那么您不能在环境变量的内容中使用括号扩展

为什么? 括号扩展由您的shell(bash)提供。当rsync 读取内容时,--exclude=$toto不会应用任何外壳扩展。更好的方法是生成要排除的文件列表,将输出重定向到文件,然后--exlcude-from=file,其中file在每一行中都包含一个文件名(或规则)。

所有引用和转义均来自rsync试图从{"*.ext1","*.ext2","*.ext3"}创建有效的Unix文件名或模式。 (基本上,您已经将rsync中的问题弄糊涂了,它正在尽您所能提供的混乱状态。)

当您将括号扩展存储在变量中时,将不应用任何shell扩展,引号失去其含义,rsync会被用来整理混乱。

查看rsync(1) - Linux manual page中的--exclude--exclude-from--filter

答案 1 :(得分:1)

这有效:

MYEXCLUDE={'*.ext1','*.ext2'}
eval rsync -av --exclude=$MYEXCLUDE src dest

如上所述,{,}触发大括号扩展(顺便说一句,示例中ext3之前的空格是问题:它阻止大括号exp)。 而且rsync的exclude选项仅接受单个模式(这意味着通过替换rsync和echo可以理解所有内容)。

偶然地,当第一行设置变量时,大括号扩展尚未发生(echo $MYEXCLUDE显示为:{*.ext1,*.ext2})。 大括号扩展发生在变量扩展后 。因此,诀窍是使用eval即时扩展。涂完全了解,比较以下两行:

MYEXCLUDE=--exclude={'*.ext1','*.ext2'}
echo $MYEXCLUDE
eval echo $MYEXCLUDE

显示

--exclude={*.ext1,*.ext2}
--exclude=*.ext1 --exclude=*.ext2