取消设置环境变量和将其设置为空字符串之间有什么实际区别吗?
答案1
每个应用程序都可以自由地以相同或不同的方式解释未设置的变量和空变量。赋予它们不同的含义通常是一个坏主意,大多数应用程序都不会这样做,但这种情况确实发生了。
shell 本身的一个例子是IFS
外壳变量(通常不会导出到环境中,但同样的原则适用)。如果未设置,shell 的行为就像该值为$' \t\n'
。
在 shell 脚本中,无论设置为空值还是未设置,$foo
都会扩展为空字符串。foo
您可以在以下位置运行 shellnounset
设置(set -u
或set -o nounset
),在这种情况下,如果您尝试扩展未设置的变量,shell 会报告错误并退出。否则,您可以使用以下命令区分未设置的变量和空变量参数扩展修饰符:如果未设置或为空,则${foo:+a}
扩展为空字符串,否则扩展为空字符串,而即使设置为空字符串,也扩展为空字符串。a
foo
${foo+a}
a
foo
答案2
是的,有区别。但这非常微妙,因为评估空字符串和未设置的变量是相同的。
$ env - FOO= sh -c 'echo "X${FOO}X X${FOO:+x}X X${FOO+x}X"; env'
XX XX XxX
FOO=
PWD=/tmp
$ env - FOO= sh -c 'unset FOO; echo "X${FOO}X X${FOO:+x}X X${FOO+x}X"; env'
XX XX XX
PWD=/tmp
两者的${FOO:+x}
计算结果都为空字符串。但当${FOO+x}
FOO 为空字符串时,将计算为“x”。
我经常使用它的一件事是设置一个$DEBUG
环境变量,然后${DEBUG+true}
在程序中使用。然后我可以将 DEBUG 设置为任何内容,包括空字符串。
在高级语言中,如 Perl 和 Python,这是“”和 undef (Perl) 或 None (Python) 之间的区别。
答案3
Bash 脚本能够区分:
- 未设置(环境)变量
- 变量设置为空
- 变量设置为空字符串
由于处理“默认回退”的可能性有很多,这三种情况之间通常没有区别。编码器倾向于只使用找到的第一个方法。一罐处理默认回退像这样:
FOO=${VARIABLE:-default} # If variable not set or null, use default.
FOO=${VARIABLE:+default} # If variable is set use, use default.
# all replacing commands an be used also without ':', so it handles null cases differently
FOO=${VARIABLE-default} # If variable not set, use default.
# somewhat also used in wild using "test" (see man test"
[[ -z "$FOO" ]] && FOO="defoltíček : "
我更愿意保留变量中使用空字符串的可能性,因此我主要使用这种方法:
DEFAULT_INTERFACE=$(ip addr show | awk '/inet.*brd/{print $NF; exit}')
INTERFACE_TO_USE=${IFACE=$DEFAULT_INTERFACE}
注意:使用IFACE=
命令将取消设置环境变量。使用IFACE=""
将变量设置为空字符串。
另请参阅类似主题https://stackoverflow.com/questions/2013547/assigning-default-values-to-shell-variables-with-a-single-command-in-bash并且设置变量以扩展为显式空字符串?