Shell:为什么 [ x"$myvar" = x0 ] 而不是 [ "$myvar" = 0 ] / 为什么向测试变量添加一个字母字符?

Shell:为什么 [ x"$myvar" = x0 ] 而不是 [ "$myvar" = 0 ] / 为什么向测试变量添加一个字母字符?

某处可能有重复(我猜),但我没有找到它:

为什么我在某些脚本中看到此类测试:

if [ x"$quiet_boot" = x0 ]

x在测试的实际变量之前添加一个?我检查了这个相关问题但当 shell 配置为在脚本使用未设置的变量时立即停止该脚本时,它会尝试避免未设置变量的问题。

那么,为什么在这里使用这个呢?

为什么不只是写作呢if [ "$quiet_boot" = 0 ]

答案1

我实际上发现重复的第二)在写这个问题时...

添加字母前缀实际上是一种解决方法一些(大部分是遗留的)test(又名[)实用程序在 shell 上下文中的实现。例如,当myvar等于-o-n或 时(,在某些情况下可能会与运算符混淆(通过添加 say 前缀可以避免这种情况x)。根据 shell 工作方式的设计,该test命令无法确定当它接收其参数时,给定的特定 arg 是运算符还是操作数。

我的test(1)手册警告:

注意:二进制 -a 和 -o 本质上是不明确的。使用“测试 EXPR1 && 测试 EXPR2”或“测试 EXPR1 ||”改为测试 EXPR2'。

所以,今天,我的 dashsh实现是这样的:

b="("
test "AAA" = "AAA" -a "$b" = "BBB"
# yields "test: closing paren expected"

x"$b" = x"BBB"可以通过或通过两个测试来避免,例如test "AAA" = "AAA" && test "$b" = "BBB".

a='='
b=x
test -n "$a" -a -n "$b"
# yields test: -a: unexpected operator

这显示了歧义,可以通过使用"$empty" = ""( 而不是-n) if-a-o正在使用来避免歧义,因此x"$empty" = x在这种情况下使用前缀 ( ) 来解决括号问题。


通常,现在:

  • 只做一个test是安全的(最多 3 个参数,不使用-o也不使用-a)并且不需要此解决方法(旧/有缺陷的实现除外),
  • 使用-o/ -a,特别是当操作数可能看起来像运算符或括号(/时)时,可能会不明确且有错误,此解决方法可以提供帮助

请注意,为了安全起见,您应该始终引用"$variables"传递给 的参数test,以便它们始终被解释为一个参数,即使它们包含空格。

更多细节,斯蒂芬·查泽拉斯写了一个相当全面的答案我鼓励您阅读这个问题。我仍然发布这个问题和答案,以便更多线索指向更容易找到的信息。

今天的实现纠正了许多导致行为不明确的遗留实现问题,因此在这些问题上,x为不使用-o或的测试添加前缀 say-a往往是不必要的。

相关内容