【问题标题】:Reason for inconsistent behavior of single quotes during BASH parameter expansion?BASH参数扩展时单引号行为不一致的原因?
【发布时间】:2018-12-14 19:12:44
【问题描述】:

当使用 BASH Parameter Expansion 时,可以引用/转义变量扩展成的字符串,这可以正常工作,除非使用单引号并且整个变量用双引号进行转义:

$ echo "${var:-\\a}"
\a # ok
$ echo "${var:-"\\a"}"
\a # ok
$ echo "${var:-$'\\a'}"
\a # ok
$ echo "${var:-'\a'}"
'\a' # wtf?

有趣的是,$' ' 引号可以正常工作,而' ' 不能。如果变量本身没有被引用,单引号开始正常工作:

$ echo ${var:-'\a'}
\a

但是,如果$var 本身包含空白字符,则可能会导致其他问题。

这种不一致有什么好的理由吗?

【问题讨论】:

  • 双引号内的单引号按字面意思保留。 echo "'foobar'" 保留了 ',但 echo ""foobar"" 没有
  • @Inian 在您的示例中,foobar 本身将不被引用。那么,为什么var2=*; echo "${var:-"$var2"}" 的输出只是*,而echo ""*"" 的输出是对所有文件的全局扩展?
  • This paragraph 似乎正在研究类似的问题。
  • 参数扩展中的引号很棘手。 bash 本身(在 4.0 发布后的某个时间)改变了对待它们的方式以遵守 POSIX 规则。
  • @chepner 我试图在发行说明中找到这样的更改,但我找不到任何东西。不过,我记得我曾经看到过与它相关的东西。

标签: bash shell quotes quoting parameter-expansion


【解决方案1】:

我认为这是源代码中最相关的引用 (y.tab.c):

  /* Based on which dolstate is currently in (param, op, or word),
     decide what the op is.  We're really only concerned if it's % or
     #, so we can turn on a flag that says whether or not we should
     treat single quotes as special when inside a double-quoted
     ${...}. This logic must agree with subst.c:extract_dollar_brace_string
     since they share the same defines. */
  /* FLAG POSIX INTERP 221 */

  [...]

  /* The big hammer.  Single quotes aren't special in double quotes.  The
     problem is that Posix used to say the single quotes are semi-special:
     within a double-quoted ${...} construct "an even number of
     unescaped double-quotes or single-quotes, if any, shall occur." */
  /* This was changed in Austin Group Interp 221 */

我不太清楚为什么单引号并不特别,但这似乎是在更改之前经过长时间(并且有人告诉我有争议)辩论后做出的有意识的选择。但事实是(如果我总结正确的话),这里的单引号只是常规字符,而不是句法引号,并且按字面意思对待。

【讨论】:

  • 有趣。不是真正的解释,但至少这是原因。我想我必须接受它。
猜你喜欢
  • 2018-06-13
  • 2015-01-16
  • 2012-01-25
  • 2015-02-28
  • 1970-01-01
  • 1970-01-01
  • 2022-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多