失败的简化示例:
FLAGS='--archive --exclude="foo bar.txt"'
rsync $FLAGS dir1 dir2
我需要包含引号,就好像命令是这样的:
rsync --archive --exclude="foo bar.txt" dir1 dir2
答案1
简短回答:参见Bash常见问题解答#50(“我试图将命令放入变量中,但复杂的情况总是失败!”)。
长答案:将命令(或命令的一部分)放入变量中,然后完整地取出它们,这很复杂。当 shell 在命令行上扩展变量时,如果变量在双引号中,则不会对其进行解析;如果变量不在引号中,则其中的空格会被解析为参数分隔符,但引号和转义符不会被解析。无论哪种情况,将引号放在变量的值中都没有任何用处。
通常,做这种事情的最佳方式是使用数组而不是简单的文本变量:
FLAGS=(--archive --exclude="foo bar.txt")
rsync "${FLAGS[@]}" dir1 dir2
答案2
评估是另一种选择:
$ x="'a b'"
$ printf '%s,%s' $x
'a,b'
$ eval printf '%s,%s' $x
a b
也可以看看:
答案3
或者,您可以为您的命令创建一个别名:
alias myrsync='rsync --archive --exclude="foo bar.txt"'
myrsync dir1 dir2
答案4
正如@cbix 所述,在这种情况下使用别名是一个很好的解决方案。
不要忘记在脚本中使用以下代码来允许别名扩展
shopt -s expand_aliases
正如这里解释的那样https://www.thegeekdiary.com/how-to-make-alias-command-work-in-bash-script-or-bashrc-file/bash 的手册页中这样说道:
当 shell 不是交互式时,别名不会展开,除非使用 shopt 设置 expand_aliases shell 选项