测试变量的感叹号在bash shell中是否为真

nat*_*han 2 shell

我知道在贝壳中感叹号可以反转条件的结果.在这里,我想用它来测试变量是真还是假.

#! /bin/bash
bat=false
if [ ! $bar ]; then
    echo 'bar is false'
else
   echo 'bar is true'
fi
Run Code Online (Sandbox Code Playgroud)

我期待'酒吧是假的'.然而事实证明了另一种方式.然后我用"$ bar"=="false".这是正确的.

那么使用感叹号的提示是什么?当我们测试文件时,它只会反转结果吗?

mkl*_*nt0 6

TL;博士

[ ! $bar ]视为$bar一个字符串,任何非空字符串都被视为"真" - 包括文字false; 换句话说:[ ! 'true' ]&& [ ! 'false' ] 评估为"false",因为操作数在两种情况下都是非空字符串并且!否定结果.

因此,您必须使用字符串比较:

bar=false
if [ ! "$bar" = 'true' ]; then  # same as: [ "$bar" != 'true' ]
    echo 'bar is false'
else
    echo 'bar is true'
fi
Run Code Online (Sandbox Code Playgroud)

在Bash中,您也可以使用[[ ! $bar == 'true' ]][[ $bar != 'true' ]]; 除非您需要保持POSIX兼容,否则我建议使用[[ ... ]].


[ ... ][[ ... ]](特定于Bash)的上下文中,默认情况下变量值是字符串,并且通常,类似POSIX的shell 没有显式的布尔数据类型.

一元运算符!将其操作数隐式解释为布尔值,布尔上下文中字符串解释如下:

  • 只有一个字符串被认为是"假"(退出代码1(!))
  • 任何非空字符串 - 包括文字 false - 都被认为是 "真"(退出代码0(!))

因此,! $bar求值为"false",因为$bar- 包含非空字符串'false'- 计算为"true",并将其!反转.


!也可以在条件之外使用,直接否定命令(包括[)的成功状态.
因为falsetrue也存在为命令名称(通常为shell内建的),你做到以下几点,但千万注意按预期与要么是文字变量的值,它仅适用falsetrue:

bar=false
if ! "$bar"; then
   echo 'bar is false'
else
   echo 'bar is true'
fi
Run Code Online (Sandbox Code Playgroud)

背景资料

类似POSIX的shell只有2种基本(标量)数据类型:

  • 字符串(默认情况下):

    • [ ... ][[ ... ]]条件句,运营商 =(==在击),< ,<= ,> ,> =`执行比较.
  • 整数:

    • [ ... ][[ ... ]]条件句,不同算术运算符(-eq,lt,le,gt,ge)必须被用于执行数值比较

    • 可选地,在算术扩展($(( ... ))), ,==,<,,<= 具有它们通常的,数字的含义. 在Bash中,您还可以将其用作算术条件.>>=
      (( ... ))

注意:根据POSIX,您不能将变量键入为整数(因为无法声明 shell变量),因此在使用算术运算符/算术上下文的比较中仅将其隐式视为一个变量.
但是,在Bash中,您可以使用/ 声明整数变量,但在条件/算术上下文中,它仍然是运算符/算术上下文的选择,它确定该值是被视为字符串还是整数.declare -ilocal -i


shell中的布尔值隐式表示为退出代码,与通常的布尔到整数映射相反:

  • "true"映射到退出代码0(!)
  • "false"表示为退出代码1(!)或任何其他非零退出代码.