Bash令人惊讶地评估"$ {x: - ''}"到(字面意思)''而不是空字符串

Dav*_*fer 1 bash

以下程序

#!/bin/bash

x=
y="${x:-''}"
z=${x:-''}
k="${x:-}"
l=${x:-}

echo "x = [$x]"
echo "y = [$y]"
echo "z = [$z]"
echo "k = [$k]"
echo "l = [$l]"
Run Code Online (Sandbox Code Playgroud)

(shellcheck说'没有发现问题')

产量

x = []
y = ['']
z = []
k = []
l = []
Run Code Online (Sandbox Code Playgroud)

表示的参数扩展${parameter:-word}bash的手册页中描述如下:

$ {parameter:-word}:使用默认值.如果参数未设置或为null,则替换单词的扩展.否则,参数的值将被替换.

如何评估"${x:-''}"字符串''中的结果而不是空字符串?

ric*_*ici 5

自扩展以来y="${x:-''}",替换词中的字符也被认为是双引号.结果类似于y=${x:"''"}在后一种情况下,$x未引用的内容(也见下面的注释).

这同样适用*于在替换中使用glob字符(例如.).

注意:正如@thatotherguy在注释中指出的那样,替换词必须具有平衡的引号(和大括号),即使引用了最外层的扩展.所以y="${x:-'}"即使y=${x:-"'"}会有效也是无效的.那是因为...

... }参数替换的结束"是第一个}没有被反斜杠或带引号的字符串转义,而不是嵌入式算术扩展,命令替换或参数扩展.

(引用man bash但非常相似的措辞可以在Posix中找到)

此外,双引号内不引用双引号.因此y="${x:-""}",所有双引号都会被引用删除删除.

  • @david:毫无疑问,shell解析是疯狂的。甚至还有比这更奇怪的极端情况(例如,反引号解析;所幸反引号已被弃用)。我也不会*预测*这种奇怪的事情;我能做的最好的就是尝试在事后解释。:-) (2认同)