[“x $ var”=“xval”]是什么点?

2021-04-12 16:53:50

在shell脚本中,您有时会遇到每个值的比较,其中每个值都以&#34为前缀。x"以下是GitHub的一些示例:

如果[" x $ {java}" =" x" ]; thenif [" x $ {server_ip}" =" Xlocalhost" ]; theif test x $ 1 =' x - 帮助' ;然后

对于任何POSIX兼容shell,x-hack的值正好零:此比较在没有x 100%的时间内工作。但为什么这是一件事?

像这个stackoverflow q&amp这样的在线来源; a是一个小的手势,称它是引用(OOF)的替代方案,指向与#34的问题;一些版本"某些炮弹,或通常警告尤其是古代UNIX系统的神秘行为,而无需具体示例。

为了确定壳检查是否应该警告这一点,如果是这样,它应该是什么,即在Unix遗产社会的档案的帮助下,我决定挖掘UNIX的历史。不幸的是,我不幸的是,无法与HP-UX和AIX相似的密切守卫世界,所以恐龙牧民要小心。

AT& T UNIX V6 Shell于1973年,至少在1977年的PWB / UNIX中找到,将无法运行测试命令,其左手SideMatched A unrare运算符。对于试图检查命令行参数的任何人来说,这必须立即显而易见:

这是在1979年的AT& T UNIX V7 Bourne Shell内置的。然而,测试和[也可作为单独的扩展物提供,并且似乎保留了越野车行为的变种:

发生这种情况是因为该实用程序使用了一个简单的递归下降解析器而不反向托管,这使得一元运算符优先于二进制运算符并忽略尾随参数。

"现代" 1988年的公共领域Kornshell复制了Bourne Shell行为,并在1992年制作了Posix.2。GNU Bash 1.14为其内置的内置和GNU Sharputils包做了同样的事情,提供了外部测试/ [二进制文件遵循POSIX ,所以早期的GNU / Linux Distors喜欢SLS没有受到影响,也不是FreeBSD 1.0。

一个类似的问题,以更长的时间才能使用String Length Operator -L。与正常的偶联谓词不同,此一个仅作为二进制谓词的操作数的一部分被解析:

它没有成功进入POSIX,因为基本原理放入它,"它在大多数实现中没有记录,已从某些实现(包括系统v)中删除,并且通过shell&#34提供功能。参考[$ {#var} -gt 8]。

在UNIX V7中不是一个问题,其中=优先于1996年的Bash 1.14将使它贪婪地解析:

$ var =" -l" $ [34; $ var" =" -L" ]测试:-L:二进制运算符预期$ [" x $ var" =" x-l" ](真的)

这也是右侧的问题,但只在嵌套表达式中。-l检查确保有第二个参数,因此您需要Anadditional表达式或括号来触发它:

$ [" $ 1" =" -L" -o 1 -eq 1] [:太多参数$ [" x $ 1" =" X-L" -o 1 -eq 1](真实) 早期壳中的另一个问题是左侧是否定运营商! $ var ="!" $ [" $ var" ="!" ]测试:参数预期(UNIX V7,1979)测试:=:Unary操作员预期(Bash 1.14,1996)(FALSE)(PD-KSH88,1988)$ [" x $ var" =" x!" ](真的) 再次,X-Hack是通过防止的! 被认为是否定运营商。 Ksh对待这一点和[! " =" ],并忽略其余的参数。 这令人害怕返回false,因为=不是null string string.ksh继续忽略这一天的尾随参数: $【-e /随机单词/ ops此处](true)(Ksh93,2021)Bash:[:太多参数(Bash5,2021) Bash 2.0和KSH93都通过Posix =在3参数案例中优先于POSIX来解决此问题。

$左="("右="(" $ [" $ left" =" $ xtrice"]测试:争论预期$ [" x $ left" =" x $右和#34;](真实)

这发生了,因为(优先于=,并且成为无效的括号组。

$左="("右="(" $ [" $ left" =" $右边和#34;] [:1:关闭彼得预期$ [" x $ left" =" x $右和#34;](真实)

令人惊讶的是,X-Hack可以习惯于在Sackoverflow将其作为过去的古老遗物写下七年之后,一直遍布某些错误。

这虫子当然越来越难以遇到。 zsh一个人只触发左翼钉针对右位的时候,否则解析器将返回并弄错。

另一个迟到的持有时间是Solaris,其/宾/ SH是遗产Bourne Shell aslate在2009年的Solaris 10.然而,这无疑是为了兼容性,而不是没有因为他们认为这是一个可行的壳牌。 A"标准兼容" Shellhad一直在Solaris 11拖动它之前长时间拖动和尖叫到21世纪 - 或者至少进入90年代 - 默认情况下2011年通过切换到KSH93。

在所有情况下,X-Hack都是有效的,因为它可以防止操作数被识别为括号。

X-Hack确实有用,对多个壳体中的几个真实和实用的问题有效。 然而,该价值大多在20世纪90年代中期的中期消失,但在2010年之前清理了几个问题 - 令人震惊的迟到,但仍然在Adecade前。 最后一个设法留在2015年之前,但只有在一个特定的非系统外壳中将括号中的括号分开的非常具体的情况下。 我认为现在是时候退役这个成语,emplackeck现在提供了一个风格的建议。 ["(" =#34;)" ]最初报道的是影响BASH 3.2.48和2008年的DASH 0.5.4的表格。您仍然可以在麦斯卡斯·贝什(Macos Bash)上看到: $ str =" -e" $ [\(!" $ str" \)[:1:关闭撬撬预期#dashbash:[:`)' 预期,找到]#bash POSIX将所有这些含糊的含义修复到最多4个参数,确保壳牌条件在任何地方都以相同的方式工作。

/ * * Posix处方:他写的,这应该得到诺贝尔*和平奖。 * /