我在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时会发生什么?
答案 0 :(得分:5)
您似乎将bash
与其他一些编程语言混淆了。变量被替换,然后剩下的就会被执行。
"$a"
这是引号之间a
的内容。 a
为空,因此相当于:
""
这不是命令。 “没有找到指令。”由于存在错误,执行不成功(shell返回代码不为0),因此命令的后半部分 - && echo 1
- 不会被执行。
...反引号
``
...执行它们之间的任何内容,该命令的输出替换整个构造。 (还有$()
也做同样的事情,并且不太容易在脚本中被忽略。)所以......
`echo "foo"`
......会评估......
foo
......然后执行。所以你...
``
...评估为......
<empty>
...然后“成功执行”(因为没有错误)。
如果您想测试 a
的内容,并且仅在echo 1
不为空时执行a
,您应该使用{{1}命令:
test
test -n "$a" && echo 1
有一个方便的别名,test
,也可以方便地忽略尾随[
...
]
...和bash-ism [ -n "$a" ] && echo 1
“知道”变量替换,因此如果[[
确实评估为空,则不需要引号来避免抱怨缺少参数。
$a
...或者,当然,更详细......
[[ -n $a ]] && echo 1
阿。错过了问题的核心部分:
if [[ -n $a ]]
then
echo 1
fi
这是两个语句,由$a && echo 1
分隔。如果第一个语句执行OK,则仅执行第二个语句。 bash将该行拆开并执行第一个语句:
&&
这是......
$a
...这是“成功的”,所以第二个语句被执行。反对...
<empty>
...是语法错误,因为没有第一个语句。 ;-)(Tricky,我知道,但这就是这个cookie崩溃的方式。)
答案 1 :(得分:0)
a=""
或
a=" " #a long empty string
然后
$> $a
将返回0
$> $noExistVar
也会返回0。
它们被“执行”,事实上,没有任何东西被执行。与按Enter或按10空格然后输入相同,您也会得到返回码0。
$> && echo 1
这会失败,因为bash会尝试执行第一部分,在这种情况下它会丢失。
$> $notExistVar && echo 1
这里有效,我猜测 bash发现$whatever
的第一部分,因此没有语法错误。然后“执行”它,没有任何执行,返回0,(与提示后按Enter键相同),然后检查,如果第一部分返回0,则在&&
之后执行cmd。
我说猜测因为我没有查看bash的源代码。如果错误请纠正我。
$> " " && echo 1
案例,我认为很清楚,不需要解释。