string 用 X"" 测试空字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6852612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 01:11:09  来源:igfitidea点击:

Test for empty string with X""

stringbashshellposix

提问by mgalgs

I know I can test for an empty string in Bash with -zlike so:

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

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

but I see a lot of code written like:

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

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

Is that method more portable? Is it just historical cruft from before the days of -z? Is it for POSIX shells (even though I've seen it used in scripts targeting bash)? Ready for my history/portability lesson.

这种方法更便携吗?难道这只是时代之前的历史遗留物-z吗?它是否用于 POSIX shell(即使我已经看到它用于脚本定位bash)?准备好我的历史/便携性课程。



The same question was asked on Server Fault as How to determine if a bash variable is empty?but no one offered an explanation as to whyyou see code with the X""stuff.

在 Server Fault 上提出的问题与如何确定 bash 变量是否为空?但没有人解释为什么你会看到带有这些X""东西的代码。

回答by Jonathan Leffler

Fundamentally, because in times now long past, the behaviour of testwas more complex and not uniformly defined across different systems (so portable code had to be written carefully to avoid non-portable constructs).

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

In particular, before testwas a shell built-in, it was a separate executable (and note that MacOS X still has /bin/testand /bin/[as executables). When that was the case, writing:

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

if [ -z $variable ]

when $variablewas empty would invoke the test program via its alias [with 3 arguments:

when $variableis empty 将通过[带有 3 个参数的别名调用测试程序:

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

because the variable was empty so there was nothing to expand. So, the safe way of writing the code was:

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

if [ -z "$variable" ]

This works reliably, passing 4 arguments to the testexecutable. Granted, the test program has been a built-in to most shells for decades, but old equipment dies hard, and so do good practices learned even longer ago.

这工作可靠,将 4 个参数传递给test可执行文件。诚然,该测试程序几十年来一直是大多数炮弹的内置程序,但旧设备难以消亡,更早以前学到的良好实践也是如此。

The other problem resolved by the X prefix was what happened if variables include leading dashes, or contain equals or other comparators. Consider (a not desparately good example):

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

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

Is that an empty string test with a stray (erroneous) argument, or a numeric equality test with a non-numeric first argument? Different systems provided different answers before POSIX standardized the behaviour, circa 1990. So, the safe way of dealing with this was:

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

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

or (less usually, in my experience, but completely equivalently):

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

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

It was all the edge cases like this, tied up with the possibility that the test was a separate executable, that means that portable shell code still uses double quotes more copiously than the modern shells actually require, and the X-prefix notation was used to ensure that things could not get misinterpreted.

这是所有像这样的边缘情况,与测试是一个单独的可执行文件的可能性有关,这意味着便携式 shell 代码仍然比现代 shell 实际需要的更多地使用双引号,并且 X 前缀符号用于确保事情不会被误解。

回答by Diego Sevilla

Ah, this is one of my preferred questions and answers, because I came up with the answer just thinking about it. The Xis set just in case the string starts with a -, that can be taken as a flag for the test. Putting an Xbefore just removes that case, and the comparison can still hold.

啊,这是我最喜欢的问题和答案之一,因为我只是想了一下就想出了答案。该X设置以防万一用的字符串开始-,可以采取作为测试的标志。放置一个Xbefore 只是删除了这种情况,并且比较仍然可以成立。

I also like this because this kind of trick is almost an inheritance from the past, oldest times of computing, and you encounter it when you try to read some of the most portable shell scripts out there (autoconf, configure, etc.)

我也喜欢这个,因为这种技巧几乎是从过去最古老的计算时代继承而来的,当您尝试阅读一些最便携的 shell 脚本(autoconf、configure 等)时会遇到它。