我知道我可以在 Bash 中测试空字符串-z
像这样:
if [[ -z $myvar ]]; then do_stuff; fi
但我看到很多代码都是这样写的:
if [[ X"" = X"$myvar" ]]; then do_stuff; fi
这种方法更便携吗?难道这只是前世的历史残骸吗?-z
?它适用于 POSIX shell(尽管我已经看到它在脚本定位中使用)bash
)?准备好我的历史/可移植性课程。
在服务器故障上也提出了同样的问题如何判断bash变量是否为空? https://serverfault.com/questions/7503/但没有人对此做出解释why你会看到代码X""
stuff.
从根本上说,因为在很久以前,test
更加复杂,并且在不同系统之间没有统一定义(因此必须仔细编写可移植代码以避免不可移植的构造)。
特别是之前test
是一个内置的 shell,它是一个单独的可执行文件(请注意,MacOS X 仍然有/bin/test
and /bin/[
作为可执行文件)。当这种情况发生时,写下:
if [ -z $variable ]
when $variable
为空将通过其别名调用测试程序[
有 3 个参数:
argv[0] = "["
argv[1] = "-z"
argv[2] = "]"
因为变量是空的所以没有什么可以扩展的。因此,编写代码的安全方法是:
if [ -z "$variable" ]
这工作可靠,将 4 个参数传递给test
可执行的。诚然,几十年来,测试程序一直内置于大多数 shell 中,但旧设备很难消亡,更早以前学到的良好实践也是如此。
X 前缀解决的另一个问题是,如果变量包含前导破折号,或者包含等于或其他比较器,则会发生什么情况。考虑一下(一个不太好的例子):
x="-z"
if [ $x -eq 0 ]
这是带有杂散(错误)参数的空字符串测试,还是带有非数字第一个参数的数字相等测试?在 POSIX 标准化行为之前(大约 1990 年),不同的系统提供了不同的答案。因此,处理此问题的安全方法是:
if [ "X$x" = "X0" ]
或者(根据我的经验,不太常见,但完全等效):
if [ X"$x" = X"0" ]
正是像这样的所有边缘情况,与测试是单独的可执行文件的可能性相关,这意味着可移植 shell 代码仍然比现代 shell 实际需要的更大量地使用双引号,并且 X 前缀表示法用于确保事情不会被误解。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)