【问题标题】:bash empty string/commandbash 空字符串/命令
【发布时间】:2016-05-19 16:21:10
【问题描述】:

我在 bash 中发现了一些奇怪的东西,我无法理解它是如何工作的。

[test ~]$ a=""
[test ~]$ $a && echo 1
1

[test ~]$ $a
[test ~]$ echo $?
0

为什么 $a(为空)返回 0?它是否以某种方式转变为空命令? 如果我在&& 之前添加引号或写空字符串,它将返回错误。而空命令返回 0。

[test ~]$ "$a" && echo 1
-bash: : command not found

[test ~]$ "" && echo 1
-bash: : command not found

[test ~]$ `` && echo 1
1

那么,当我输入 $a 时会发生什么?

【问题讨论】:

  • 这可能是bash 的解析器中的一个错误。 "$a" && echo 1 产生错误,因为空字符串不是有效命令。 && echo 1 产生语法错误。 $a && echo 1 应该产生相同的语法错误,但似乎与 `: && echo 1 行为相同。
  • 实际上,我猜解析器在$a 评估为空之前识别出两个由&& 分隔的命令,此时它被视为空命令而不是解析错误。
  • ...aside:变量不应该首先用于存储命令。请参阅 BashFAQ #50,mywiki.wooledge.org/BashFAQ/050
  • 分号:$a; echo hello 和子shell ( $a ) 和组{ $a; } 也会发生同样的事情。

标签: linux string bash


【解决方案1】:
a=""

a="                       " #a long empty string

然后

$> $a

将返回 0

$> $noExistVar

也会返回 0。

他们被“执行”,事实上,没有任何东西被执行。就像你按回车或按 10 个空格然后回车一样,你也会得到返回码 0。

$>       && echo 1

这将失败,因为 bash 将尝试执行第一部分,在这种情况下它丢失了。

$> $notExistVar && echo 1

这里可以了,我 bash 找到了第一部分$whatever,因此没有语法错误。然后“执行”它,什么都不执行,返回0,(提示符后按回车),然后检查,如果第一部分返回0,则执行&&之后的cmd。

我说猜测是因为我没有检查 bash 的源代码。如有错误请指正。

$> " " && echo 1的情况,我觉得很清楚,不用解释了。

【讨论】:

    【解决方案2】:

    您似乎将bash 与其他一些编程语言混淆了。变量被替换,然后剩下的被执行。

    "$a"
    

    这是a 的内容,用引号括起来。 a 为空,所以这相当于:

    ""
    

    那不是命令。 “找不到命令。”由于出现错误,执行不成功(shell返回码不为0),所以命令的后半部分——&& echo 1——没有被执行。

    反引号...

    ``
    

    ...执行它们之间的任何内容,该命令的输出替换整个构造。 (也有 $() 做同样的事情,并且不太容易在脚本中被忽视。)所以...

    `echo "foo"`
    

    ...将评估为...

    foo
    

    ...然后将被执行。所以你的...

    ``
    

    ...计算为...

     <empty>
    

    ...然后“执行成功”(因为没有错误)。

    如果你想测试a的内容,只有在a不为空时才执行echo 1,你应该使用test命令:

    test -n "$a" && echo 1
    

    test 有一个方便的别名,即[,它也可以方便地忽略尾随的]...

    [ -n "$a" ] && echo 1
    

    ...和一个 bash-ism [[ “知道”变量替换,因此如果 $a 确实评估为空,则不需要引号以避免抱怨缺少参数...

    [[ -n $a ]] && echo 1
    

    ...或者,当然,更冗长...

    if [[ -n $a ]]
    then
        echo 1
    fi
    

    啊。错过了问题的核心部分:

    $a && echo 1
    

    这是两个语句,以&amp;&amp; 分隔。只有当第一个语句执行正常时,第二个语句才会执行。 bash 将行拆开并执行第一条语句:

    $a
    

    这是……

    <empty>
    

    ...这是“成功的”,所以第二条语句被执行。反对...

    && echo 1
    

    ...是语法错误,因为没有第一条语句。 ;-)(棘手,我知道,但这就是这个 cookie 崩溃的方式。)

    【讨论】:

    • 不过,您还没有解释为什么 $a &amp;&amp; echo 1 会产生这样的结果。
    • @chepner:正如您评论的那样。 ;-)
    • 另外,我将解析与评估混为一谈。 $a &amp;&amp; echo 1 不进行参数扩展,而是解析器识别出两个命令$aecho 1,每个命令都是单独评估的。
    猜你喜欢
    • 2021-05-23
    • 1970-01-01
    • 2011-02-20
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 2014-12-06
    • 2017-07-06
    相关资源
    最近更新 更多