我有一个简单的测试bash脚本,如下所示:
#!/bin/bash
cmd="rsync -rv --exclude '*~' ./dir ./new"
$cmd # execute command
当我运行脚本时,它也会复制以~
结尾的文件,即使我想要排除它们。当我直接从命令行运行相同的rsync命令时,它可以工作!有人知道为什么以及如何使bash脚本工作吗?
--exclude-from
,但我想知道它是如何工作的。
答案 0 :(得分:6)
尝试 eval :
#!/bin/bash
cmd="rsync -rv --exclude '*~' ./dir ./new"
eval $cmd # execute command
答案 1 :(得分:5)
问题不在于您是在脚本中运行它,而是将命令放在变量中然后运行扩展变量。并且由于在已经完成引用删除之后发生了可变扩展,因此排除模式周围的单引号永远不会被删除...因此rsync将排除名称以“以〜结尾”的文件排除。要解决此问题,只需删除模式周围的引号(整个内容已经是双引号,因此不需要它们):
#!/bin/bash
cmd="rsync -rv --exclude *~ ./dir ./new"
$cmd # execute command
...说到哪,为什么在运行之前将命令放在变量中?一般来说,这是使代码比它需要更混乱的好方法,并触发解析奇怪(有些甚至比这更奇怪)。那怎么样:
#!/bin/bash
rsync -rv --exclude '*~' ./dir ./new
答案 2 :(得分:0)
您可以使用简单的--eclude '~'
(根据手册页):
- 如果模式以a开头,那么它将锚定到某个特定位置 文件的层次结构,否则它 匹配结束 路径名。这类似于领先 ^在正则表达式中。因此“/ foo” 将匹配“foo”的名称 “转移的根源”(对于a 全局规则)或在合并文件中 目录(对于每个目录规则)。 不合格的“foo”会匹配a 树中任何地方的“foo”名称 因为算法已应用 从上到下递归;它 表现得好像每个路径组件都有 转向结束了 文件名。即使是未经发现的 “sub / foo”会在任何一点匹配 找到“foo”的层次结构 在名为“sub”的目录中。看到 关于锚定的部分 包括/排除完整的模式 讨论如何指定模式 匹配的根源 传输。
- 如果模式以/结尾,则它只匹配目录,而不是a 常规文件,符号链接或设备。
- rsync在执行简单的字符串匹配和通配符之间进行选择 通过检查模式进行匹配 包含这三个通配符中的一个 字符:'*','?'和'['。
- a'*'匹配任何路径组件,但它会以斜杠停止。
- 使用'**'来匹配任何内容,包括斜杠。