$ {var}和$ {var-}之间有什么区别

olo*_*opo 6 bash

我已经看到一些shell脚本使用这个变量引用表示法,我只是找不到任何信息.

就我的测试而言,它显然是一样的.

有线索吗?

$ uno=1
$ if [ -n "${uno}" ]; then echo yay\! ; fi
yay!
$ if [ -n "${uno-}" ]; then echo yay\! ; fi
yay!
Run Code Online (Sandbox Code Playgroud)

Ben*_* W. 6

从 Bash 手册中,关于参数扩展

${parameter:-word}

如果参数未设置或为空,则替换单词的扩展。否则,将替换参数的值。

在您的情况下,word是空字符串,并且省略了冒号。如果没有冒号,则检查仅针对未设置,而不针对 null,因此${uno-}相当于检查是否uno已设置(请参阅如何检查 Bash 中是否设置了变量?),如果没有,则将其扩展为空string – 保证扩展不会被取消设置。

这取决于上下文,这有什么好处;在你的例子中,这确实没有什么区别。

结果上下文是一个set -u使用的脚本 -有关详细信息,请参阅John 1024 的答案。


Joh*_*024 5

${uno-}是在uno未设置参数的情况下提供默认值的示例.

如果uno未设置,我们得到以下字符串-:

$ unset uno
$ echo ${uno-something}
something
Run Code Online (Sandbox Code Playgroud)

如果uno只是空字符串,则uno返回值:

$ uno=""
$ echo ${uno-something}

$
Run Code Online (Sandbox Code Playgroud)

如果uno具有非空值,则返回该值:

$ uno=Yes
$ echo ${uno-something}
Yes
Run Code Online (Sandbox Code Playgroud)

为何使用${variable-}

当脚本的正确操作很重要时,脚本编写器通常会使用set -u在任何时候使用未设置的变量时生成错误消息.例如:

$ set -u
$ unset uno
$ echo ${uno}
bash: uno: unbound variable
Run Code Online (Sandbox Code Playgroud)

要处理可能要禁止此消息的特殊情况,-可以使用尾随:

$ echo ${uno-}

$ 
Run Code Online (Sandbox Code Playgroud)

[认为OP的完整代码使用set -u及其对此问题的重要性归功于Benjamin W.

文档

man bash

当不执行子串扩展时,使用下面记录的表单(例如:-),bash测试未设置或为null的参数. 省略冒号只会导致对未设置的参数进行测试.

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

  • @olopopo冒号在手册的引用中提到. (2认同)