某处可能有重复(我猜),但我没有找到它:
为什么我在某些脚本中看到此类测试:
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
往往是不必要的。