bash 报价扩展拼图

Dav*_* S. 2 bash quoting

我的脚本看起来像:

opts="-x ''"
curl http://somepage $opts
Run Code Online (Sandbox Code Playgroud)

我希望将字符串$opts附加到命令中。我bash -x test.sh用来检查扩展并看到单引号被删除。

如果我将其更改为:

opts="-x \'\'"
Run Code Online (Sandbox Code Playgroud)

展开后有4个单引号。

Gil*_*il' 5

你究竟看到了什么?随着脚本

opts="-x ''"
echo curl http://somepage $opts
opts="-x \'\'"
echo curl http://somepage $opts
Run Code Online (Sandbox Code Playgroud)

使用 bash 3.2.39 或 4.1.5,我看到

+ opts='-x '\'''\'''
+ echo curl http://somepage -x ''\'''\'''
curl http://somepage -x ''
+ opts='-x \'\''\'\'''
+ echo curl http://somepage -x '\'\''\'\'''
Run Code Online (Sandbox Code Playgroud)

第一次调用curl(well, echo curl) 有一个由两个字符组成的最后一个参数''。跟踪转义特殊字符:'显示为'\''(在单引号内“转义”单引号的常见习语)。正式地,''\'''\'''由一个空的单引号字符串组成,''后跟反斜杠引用的字符\',然后再次'',再次\'和最后一个''。(Ksh 将此显示为稍微更易读的$'\'\''。)第二个调用传递了四个字符\'\'

在正常的 sh 解析规则下,你不能通过扩展一个不带引号的变量来创建一个空参数。分词只会在有非空格或引用字符的地方进行切割。

由于您使用的是 bash,因此您可以将多个选项放入一个数组中。这也适用于 ksh 和 zsh。

opts=(-x "")
curl http://somepage "${opts[@]}"
Run Code Online (Sandbox Code Playgroud)

对于这种特殊情况,您可以改写环境变量。

http_proxy= curl http://somepage
Run Code Online (Sandbox Code Playgroud)

  • +1 用于使用数组。如果它们可用,那么使用其他任何东西都是疯狂的。将此答案的第一部分与数组解决方案的简单性进行比较。 (2认同)