条件中不带冒号的参数展开(默认空串)的作用及Shell兼容性疑问
${NVM_PROFILE-} in [ -z "${NVM_PROFILE-}" ] Great question! Let's unpack why this syntax is used, focusing on shell strict mode and cross-shell compatibility.
First, a quick recap of the parameter expansion at play:
${var-word}: Ifvaris undefined, replace it withword; ifvaris defined (even if empty), use the variable's current value.- Here,
wordis an empty string (since nothing follows the-), so${NVM_PROFILE-}translates to:- If
NVM_PROFILEdoesn’t exist at all, expand to an empty string. - If
NVM_PROFILEis defined (whether it’s empty or has a value), use its existing value.
- If
Now let’s break down the two core reasons for using this syntax in the -z check:
1. Prevent crashes in strict mode (set -u)
Many scripts enable set -u (also called nounset), which makes the shell throw an error and exit if you reference an undefined variable.
Without ${NVM_PROFILE-}, writing [ -z "$NVM_PROFILE" ] would crash the script if NVM_PROFILE is undefined and set -u is active. The ${NVM_PROFILE-} syntax guarantees that even if the variable doesn’t exist, it expands to an empty string—so the -z check (which tests for an empty string) runs safely without triggering an error.
2. Ensure cross-shell compatibility
While Bash treats undefined variables as empty by default (without set -u), other shells like zsh or older POSIX-compliant shells can have subtle differences in how they handle undefined variables.
Using ${var-} standardizes behavior across all POSIX shells: no matter the shell, the expansion will always result in either the variable’s value (if defined) or an empty string (if not). This eliminates edge cases where a shell might treat an undefined variable differently, breaking the -z check logic.
Quick side note: ${NVM_PROFILE-} vs ${NVM_PROFILE:-}
You might wonder why we use - instead of :- here. Since our "fallback" value is an empty string, both syntaxes produce the same result in this scenario:
${NVM_PROFILE:-}replaces with empty if the variable is undefined OR empty${NVM_PROFILE-}replaces with empty only if the variable is undefined
But since we’re checking for an empty string with -z, both end up serving our needs. The choice of - is often stylistic, to explicitly signal we’re only handling the "undefined" case (even though the end result matches what we need for the check).
内容的提问来源于stack exchange,提问作者whoan

