string - 使用 X""测试空字符串

标签 string bash shell posix

<分区>

我知道我可以在 Bash 中使用 -z 测试空字符串,如下所示:

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

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

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

那个方法更便携吗?这只是 -z 时代之前的历史遗留问题吗?它是否用于 POSIX shell(尽管我已经看到它用于针对 bash 的脚本)?为我的历史/便携性类(class)做好准备。


在 Server Fault 上提出了与 How to determine if a bash variable is empty? 相同的问题但没有人解释为什么您会看到带有 X"" 内容的代码。

最佳答案

从根本上说,因为在很久以前,test 的行为更加复杂并且在不同系统之间没有统一定义(因此必须仔细编写可移植代码以避免不可移植的构造)。

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

if [ -z $variable ]

$variable 为空时,将通过其别名 [ 使用 3 个参数调用测试程序:

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

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

if [ -z "$variable" ]

这可靠地工作,将 4 个参数传递给 test 可执行文件。诚然,测试程序几十年来一直是大多数 shell 的内置程序,但旧设备经久耐用,更早以前学到的良好做法也是如此。

X 前缀解决的另一个问题是,如果变量包含前导破折号,或包含等号或其他比较器,会发生什么情况。考虑(一个不太好的例子):

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

这是带有杂散(错误)参数的空字符串测试,还是带有非数字第一个参数的数字相等性测试?在大约 1990 年 POSIX 标准化行为之前,不同的系统提供了不同的答案。因此,处理这个问题的安全方法是:

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

或(根据我的经验,不太常见,但完全等同):

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

所有的边缘情况都是这样的,与测试是一个单独的可执行文件的可能性相关联,这意味着可移植的 shell 代码仍然比现代 shell 实际需要的更大量地使用双引号,以及 X 前缀符号用于确保事情不会被误解。

关于string - 使用 X""测试空字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6852612/

相关文章:

linux - Bash 或 Awk 脚本合并 X 个字段匹配的行,同时在不匹配的字段中创建范围

linux - 只得到grep : get ip of ifconfig的第一部分

c++ - 在文件中写入新行字符

python计算序列列表中子字符串的存在和不存在的数量

python - 性感无法处理 unicode 字符串?

linux - 查找在过去 15 分钟内更改的文件,不包括一些子目录并将其压缩

linux - 如何使用 'tee' 运行命令并保存输出?

linux - 从列表中填充数组;如果没有回车则不读取项目

linux - 如何填充 CSV 文件缺失的列

c - 在C中的字符串char数组中搜索字符串