在 bash 中使用 :- (冒号破折号)

Posted

技术标签:

【中文标题】在 bash 中使用 :- (冒号破折号)【英文标题】:Usage of :- (colon dash) in bash 【发布时间】:2022-01-24 02:31:42 【问题描述】:

这个样式在bash中是什么意思?

$PUBLIC_INTERFACE:-eth0

:-的目的是什么?

【问题讨论】:

【参考方案1】:

如果$PUBLIC_INTERFACE存在且不为null,则返回其值,否则返回"eth0"

bash man page 中实际上记录了其中一些:

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

$parameter:=word 分配默认值。如果参数未设置或为空,则将单词的扩展分配给参数。然后替换参数的值。位置参数和特殊参数不能这样赋值。

$parameter:?word 如果为 Null 或未设置,则显示错误。如果 parameter 为 null 或未设置,则 word 的扩展(或者如果 word 不存在,则将产生一条消息)写入标准错误,并且 shell,如果它不是交互式的,则退出。否则,参数的值被替换。

$parameter:+word 使用替代值。如果参数为null或未设置,则不替换任何内容,否则替换单词的扩展。

【讨论】:

【参考方案2】:

:- 用于$<em>parameter</em>:-<em>word</em> shell parameter expansion:如果 parameter 为 null 或未设置,则扩展为 word 的值,否则为 parameter 的值。

例子:

$ str=
$ echo "$str:-default"
default

这个和使用:=:+:? 的类似扩展都有两种风格:带冒号和不带冒号。不同之处在于扩展with冒号表示“未设置或null”,而不带冒号只是“未设置”。

观察:

$ str=                      # Null, but not unset
$ echo "$str-default"     # Expands to value of $str, the empty string
    
$ echo "$str:-default"    # Expands to "default"
default

这在哪里有用?几个例子:

默认值

调用编辑器以编辑带有fc 的最后一个命令是扩展$FCEDIT:-$EDITOR:-vi 的结果:$FCEDIT 如果已定义且不为空,或者$EDITOR 如果已定义且不为空,或者vi .

脚本中的循环如果作为参数提供,则应从文件中读取,否则从标准输入中读取,可能如下所示:

while IFS= read -r line; do
    # do something
done < "$1:-/dev/stdin"

使用set -u

set -u 是一种方便的方法,通过在遇到未设置的变量时让脚本死掉来强制编写更简洁的脚本,例如 this article 所提倡的(并不是我认可那里的所有内容1) .如果我们想检查某个变量是否具有[[ $var ]] 的值,如果未设置var,脚本现在就会终止,即使这可能是合法的。

解决方法是改用[[ $var:- ]]set -u 不会抱怨。 (这基本上是再次使用默认值,但在这种情况下替换的值是空字符串。2

顺便说一下,这些扩展并不是 Bash 独有的:POSIX shell spec 也拥有它们。


1另见BashFAQ/112, What are the advantages and disadvantages of using set -u (or set -o nounset)?

2 只需$var- 而不是$var:- 实际上就足够了:set -u 不关心已设置但包含空字符串的变量;只有未设置的会触发错误。

【讨论】:

set -u 解决方法中,为什么用[[ $var:- ]] 而不是[[ $var- ]] @wjandrea var- 就足够了,set -u 不会抱怨已设置但包含空字符串的变量的扩展。

以上是关于在 bash 中使用 :- (冒号破折号)的主要内容,如果未能解决你的问题,请参考以下文章

冒号的解释及造句

为啥不能在 bash 4.1.2 中访问带有破折号的环境变量?

bash、破折号和字符串比较

FFmpeg 如何使用 bash 生成视频序列

bash,在冒号前提取字符串

Bash / Zsh - 导出环境变量,其名称包含冒号