shell 脚本的美元括号内的减号是什么意思?

Mat*_*ins 11 bash shell-scripting

在现有的 shell 脚本中,我看到一些引用的变量包含或以减号结尾。例如:

PID=${PID-/run/unicorn.pid}
Run Code Online (Sandbox Code Playgroud)

和:

run_by_init() {
    ([ "${previous-}" ] && [ "${runlevel-}" ]) || [ "${runlevel-}" = S ]
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,减号是什么意思?

And*_*man 10

根据 bash 手册页中的“参数扩展”部分,这意味着“如果未设置参数,则使用默认值”。例如,

${PID-/run/unicorn.pid}
Run Code Online (Sandbox Code Playgroud)

如果设置了 $PID,则等于 $PID,否则为 /run/unicorn.pid。


pap*_*apo 9

应该强调的是,这意味着一个未设置的变量。不是空的。
并与 进行比较:-,如果变量未设置或为空(如在空字符串中),它将使用默认值(减号后的那个)。
减去没有冒号不被视为经常(至少不是我),并有更具体的使用比:-它甚至没有提到GNU手册,而不是我的man bash,但它例如描述上TLDP

在需要替换默认值的情况下,当变量不包含合理值时。后者更合适。

PID=${PID-/run/unicorn.pid}
PID 可能已被使用,然后在脚本中使用 PID="" 清空。此关联将失败,PID 将保留为空字符串“”

PID=${PID:-/run/unicorn.pid}
如果未设置,PID 将变为 "/run/unicorn.pid",但即使之前为空 ("")。

没有默认值的构造${previous-}被认为是防止某人set -u

set -u|名词集

执行参数扩展时,将未设置的变量和特殊参数 '@' 或 '*' 以外的参数视为错误。错误消息将写入标准错误,并且非交互式 shell 将退出。
https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html

set -u
[ "${previous}" ] || echo "This will fail"
[ "${previous-}" ] || echo "This works"
Run Code Online (Sandbox Code Playgroud)