Bashtesting空string与X“”

我知道我可以用-z来testingBash中的空string,就像这样:

 if [[ -z $myvar ]]; then do_stuff; fi 

但是我看到很多代码是这样写的:

 if [[ X"" = X"$myvar" ]]; then do_stuff; fi 

这种方法更便携吗? 这只是从-z之前的历史遗留下来的吗? 它是POSIX shell(尽pipe我已经看到它用在针对bash脚本中)吗? 准备好我的历史/可移植性课程。


服务器故障问同样的问题如何确定一个bashvariables是否为空? 但没有人提供解释, 为什么你看到X""东西的代码。

从根本上说,因为在过去很久以前, test的行为比较复杂,并且在不同的系统中没有统一的定义(所以便携式代码必须仔细书写以避免非便携式结构)。

特别是在test之前是一个内置的shell,它是一个单独的可执行文件(注意MacOS X仍然具有/bin/test/bin/[作为可执行文件])。 当情况如此时,写作:

 if [ -z $variable ] 

$variable为空时将通过其别名调用testing程序[有3个参数:

 argv[0] = "[" argv[1] = "-z" argv[2] = "]" 

因为variables是空的,所以没有什么可扩展的。 所以编写代码的安全方式是:

 if [ -z "$variable" ] 

这可靠地工作,将4个parameter passing给test可执行文件。 诚然,testing计划几十年来一直是大多数炮弹的内置工具,但是老旧的设备很难死亡,所以在更早的时候学到的好的实践也是如此。

由X前缀解决的另一个问题是如果variables包含前缀破折号或者包含equals或其他比较符时发生的情况。 考虑(一个不是很好的例子):

 x="-z" if [ $x -eq 0 ] 

这是一个空stringtesting与一个杂散(错误)的参数,或数字相等性testing与非数字的第一个参数? 不同的系统提供了不同的答案,POSIX规范了这种行为,大约在1990年。所以,处理这个问题的安全方法是:

 if [ "X$x" = "X0" ] 

或者(通常,根据我的经验,但完全相同):

 if [ X"$x" = X"0" ] 

这是所有这样的边缘情况,与testing是一个单独的可执行文件的可能性绑定,这意味着可移植shell代码仍然使用双引号比现代shell实际需要更多,并且X前缀符号被用来确保事情不会被误解。

啊,这是我最喜欢的问题和答案之一,因为我想出了答案。 X的设置是为了防止string以-开始,这可以作为testing的标志。 在删除这种情况之前放一个X ,比较依然可以。

我也喜欢这个,因为这种技巧几乎是从过去,也就是最古老的计算的inheritance,而当你尝试阅读一些最便携的shell脚本(autoconf,configure等)