【问题标题】:Bash null binary operatorsBash 空二元运算符
【发布时间】:2013-02-16 04:09:38
【问题描述】:

我最近进行的一项测试对以下bash 命令的输出有疑问:

var=; [ -n $var ]; echo $?; [ -z $var ]; echo $?

结果为@​​987654323@ 和0,表示两个一元运算符的返回码都没有错误。这意味着$var 解析为null(空)和“非空”(非空),对吗?

这怎么可能?

【问题讨论】:

  • 这些是一元运算符。
  • info coreutils test invocation 16.3.4 字符串测试

标签: linux bash binary-operators


【解决方案1】:

不,这意味着[ 已无法修复。在这两种情况下,$var 的计算结果都为空,并且命令只需分别执行[ -n ][ -z ],这两个结果都为真。如果你想测试变量本身的值,那么你必须引用它才能正确处理它。

$ var=; [ -n "$var" ]; echo $?; [ -z "$var" ]; echo $?
1
0

【讨论】:

  • 不是unfixably broken;它只是具有非直觉的行为。 [ -n ] 正确报告字符串-n 不为空,[ -z ] 正确报告字符串-z 不为空。
【解决方案2】:

你需要把 $var 括起来:

$ [ -n "$var" ]; echo $?
1

请记住,右方括号只是语法糖:你不需要它。这意味着您的线路:

$ [ -n $var ]; echo $?

将扩展为(因为 $var 为空):

$ [ -n  ]; echo $?

上面的问题是:“字符串']'是非空的吗?”答案是肯定的。

【讨论】:

  • 虽然[ 不是语法,实际上是test 命令的同义词,但您确实需要使用结束][
【解决方案3】:

确实令人惊讶。如果您尝试使用 bashism [[ 语法进行相同操作,您将得到 10 作为结果。我认为这是一个错误。

var=; [[ -n $var ]]; echo $?; [[ -z $var ]]; echo $?

或者,正如 Ignacio 指出的那样,事实上我一直在直觉地做防御性编码和引用:

var=; [[ -n "$var" ]]; echo $?; [[ -z "$var" ]]; echo $?

[ 的行为方式让我感到惊讶,因为它是内置的:

$ type [
[ is a shell builtin

刚刚做了一点测试,系统命令[ 的行为方式与内置命令相同。所以可能是兼容性问题:

var=; /usr/bin/\[ -n $var ]; echo $?; /usr/bin/\[ -z $var ]; echo $?

【讨论】:

  • [ 有很多无法修改的遗留行为,因为脚本依赖于默认行为。有点像 Windows API。
  • @Ignacio Vazquez-Abrams:刚刚注意到。很有趣。
猜你喜欢
  • 2021-11-14
  • 1970-01-01
  • 2023-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
相关资源
最近更新 更多