我想将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理解的,并且完全感到困惑。
有人能解释这种“引号和转义字符”行为背后的原因吗?
答案 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