Bash - 如果语法混乱

Jae*_*ner 6 bash

因此,作为 GIT 的新手,因此在我的 bash 命令和脚本编写方面非常生疏,我一直在寻找不同的语法和脚本帮助。现在,我找到了很多帮助,并且能够创建脚本和别名,这将使我的 Git 体验更加愉快。

但是,我遇到了一些似乎让我感到困惑的细微差别,特别是与“if”命令相关的细微差别。

if [ -z $1 ] ; #<- Zero length string
if [[ -z $1 ]] ; #<- Also Zero Length String
if [[ "$1" == -* ]] ; #<- Starts with - (hyphen)


if [ -z $1 ] && [ -z $2 ] ; #<- both param 1 & 2 are zero length
if [[ -z $1 ]] && [[ -z $2 ]] ; #<- Also both param 1 & 2 are zero length
if [[ "$1" == -* ]] || [[ "$2" == -* ]] ; #<- Either param 1 or 2 starts with -

if [ "$1" == -* ] || [ "$2" == -* ] ; #<- Syntax Failure, "bash: ]: too many arguments"
Run Code Online (Sandbox Code Playgroud)

为什么会出现差异?如何知道何时需要 [[ (double) 以及何时需要 [ (single) 呢?

感谢 Jaeden "Sifo Dyas" al'Raec Ruiner

dha*_*hag 13

首先,请注意,两种类型的括号都不是 if. 反而:

  • [是 shell 内置的另一个名称test
  • [[ ... ]] 是一个单独的内置函数,具有不同的语法和语义。

以下是 bash 文档的摘录:

[ / test

test: test [expr]
    Evaluate conditional expression.

    Exits with a status of 0 (true) or 1 (false) depending on
    the evaluation of EXPR.  Expressions may be unary or binary.  Unary
    expressions are often used to examine the status of a file.  There
    are string operators and numeric comparison operators as well.

    The behavior of test depends on the number of arguments.  Read the
    bash manual page for the complete specification.

    File operators:

      -a FILE        True if file exists.
      (...)
Run Code Online (Sandbox Code Playgroud)

[[ ... ]]

[[ ... ]]: [[ expression ]]
    Execute conditional command.

    Returns a status of 0 or 1 depending on the evaluation of the conditional
    expression EXPRESSION.  Expressions are composed of the same primaries used
    by the `test' builtin, and may be combined using the following operators:

      ( EXPRESSION )    Returns the value of EXPRESSION
      ! EXPRESSION              True if EXPRESSION is false; else false
      EXPR1 && EXPR2    True if both EXPR1 and EXPR2 are true; else false
      EXPR1 || EXPR2    True if either EXPR1 or EXPR2 is true; else false

    When the `==' and `!=' operators are used, the string to the right of
    the operator is used as a pattern and pattern matching is performed.
    When the `=~' operator is used, the string to the right of the operator
    is matched as a regular expression.

    The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to
    determine the expression's value.

    Exit Status:
    0 or 1 depending on value of EXPRESSION.
Run Code Online (Sandbox Code Playgroud)

更简单地说,[需要对 bash 表达式、引用以避免插值等进行正常处理。因此,测试是否$foo为空字符串或未设置的正确方法是:

[ -z "$foo" ]
Run Code Online (Sandbox Code Playgroud)

或者

[[ -z $foo ]]
Run Code Online (Sandbox Code Playgroud)

在第一种情况下引用很重要,因为设置foo="a b" 然后测试[ -z $foo ]会导致test -z接收两个参数,这是不正确的。

for 的语言[[ .. ]]是不同的,并且正确地了解变量,这与人们对比 bash 更高级的语言所期望的方式非常相似。因此,它比经典[/更不容易出错test