【问题标题】:When do if constructs not require brackets?if 结构什么时候不需要括号?
【发布时间】:2014-11-03 23:55:05
【问题描述】:

我正在为一个 shell 脚本类做一些功课,并且有一个问题要求我编写一个脚本来测试输入的参数是否是一个有效的 shell 变量名。下面的脚本似乎工作正常。

if echo "$1" | grep -v ".*[^A-Za-z_]" > /dev/null
then
        echo yes
else
        echo no
fi

我知道括号是 BASH shell 中测试功能的简写。我的问题是,当我尝试使用方括号执行上述脚本时出现错误。

if [ echo "$1" | grep -v ".*[^A-Za-z_]" > /dev/null ]

这个问题(我相信)是 grep 试图使用 ] 作为其参数,因此在运行脚本时会导致错误。

什么情况下不需要括号?

【问题讨论】:

    标签: linux bash if-statement grep brackets


    【解决方案1】:

    [ 实际上是一个命令(它恰好内置在大多数 shell 中),而不仅仅是 if 语句语法的一部分。

    if 语句执行作为其参数的命令。如果该命令成功(将$? 设置为零),则条件为真;如果它失败(将$? 设置为某个非零值),则条件为假。

    内置的[ 命令几乎完全等同于test 命令;不同之处在于[ 需要] 作为其最后一个参数。

    另见https://unix.stackexchange.com/a/22728/10454

    【讨论】:

      【解决方案2】:

      [/test 是一个命令(也是内置的),正如你所说。它是一个命令,它接受特定类型的参数并在给定这些参数的情况下以特定方式运行。

      它接受标志和比较运算符并对它们进行操作以获得truefalse 结果。然后它将结果转换为返回码。 0true1false

      定义了shell中的if构造

      如果列表;然后列出; [ elif 列表;然后列出; ] ... [ 其他列表; ] 菲

      if 列表被执行。如果其退出状态为零,则执行 then 列表。否则,依次执行每个elif列表,如果其退出状态为零,则执行对应的then列表,命令完成。否则,执行 else 列表(如果存在)。退出状态是最后执行的命令的退出状态,如果没有条件测试为真,则为零。

      所以当[/test 返回一个退出代码时,if 会评估。

      echo 命令/管道周围不需要(也不能使用)[ 的原因是因为这不是一组有效的[ 参数。相反,这是一个命令list 本身,因此不需要由[ 评估。您可以直接使用它并将管道的返回码交给if进行评估。

      【讨论】:

      • 感谢您的回复,最后一点特别解决了我的困惑。我没有意识到命令有返回码。
      • @xcerule 最新命令的返回码存储在$?中。 “最近”位很重要,因为它会影响诸如 'some_complex_command; echo "状态信息";如果 [ $? -ne 0 ];然后... fi`,很多人偶然尝试了它,却没有意识到他们刚刚用echo的返回码破坏了他们复杂命令的返回码。此外,管道的返回码是管道中最后一条命令的返回码(无论其他命令返回什么,但请参阅 bash 手册页中的 pipefail$PIPESTATUS 变量了解更多信息)。跨度>
      【解决方案3】:

      您也可以使用双方括号 [[ 代替单方括号 [

      在此处了解更多信息:http://mywiki.wooledge.org/BashFAQ/031:

      [ ("test" command) and [[ ("new test" command) are used to
      evaluate expressions. [[ works only in Bash, Zsh and the Korn shell,
      and is more powerful; [ and test are available in POSIX shells
      

      【讨论】:

      • 呃,引用的时候格式有点丢失,很难知道什么是最好的格式。
      猜你喜欢
      • 2013-04-07
      • 1970-01-01
      • 2019-08-13
      • 2020-01-09
      相关资源
      最近更新 更多