为什么在这个简单的 shell 脚本中注释掉看似无关的代码会引发错误?

Why does commenting out seemingly-unrelated code in this simple shell script throw an error?

这让我难住了。在 macOS Catalina 中 shell 编写脚本和使用 ZSH 的新手(尽管我认为同样的事情也会在 bash 中发生。)

我有以下正在使用的脚本,我已将其保存在一个名为 f 的文件中,该文件没有扩展名。我用 -x chmod 将它放在路径变量中的本地 bin 文件夹中。

clear

echo "Argument Count: $#"

if [ $# == 0 ]; # Run if no arguments
then 
    echo "You ran this with no arguments!"
    exit 0
fi

if [  == "a" ]; # Run if the first argument is 'a'
then
    echo "You ran A!"
    exit 0
fi

# Run if nothing matches the above
echo "No matches!"

以上如我所料。如果我输入这个...

f

我明白了...

Argument Count: 0
You ran this with no arguments!

如果我输入这个...

f a

我明白了...

Argument Count: 1
You ran A!

最后,如果我输入这个...

f b (or f c, f foo, etc.)

我明白了...

Argument Count: 1
No matches.

再一次,工作完全符合我的预期。

但是,如果我将脚本更改为此,我只需注释掉第一个 if 块...

clear

echo "Argument Count: $#"

# if [ $# == 0 ]; # Run if no arguments
# then 
#   echo "You ran this with no arguments!"
#   exit 0
# fi

if [  == "a" ]; # Run if the first argument is 'a'
then
    echo "You ran A!"
    exit 0
fi

# Run if nothing matches the above
echo "No matches!"

...我自己输入 f,我现在明白了!

Argument Count: 0
/Users/[redacted]/bin/f: line 11: [: ==: unary operator expected
No matches!

注意:如果第一个参数是'a'[=61=,第11行是注释#运行 ]

更奇怪的是,如果我输入以下内容,它会直接运行它抱怨的第 11 行的代码...

f a

我明白了,它工作正常!

Argument Count: 1
You ran A!

那我到底错过了什么??

当你 运行 你的脚本没有参数时,这个表达式:

if [  == "a" ]; 

变为:

if [ == "a" ];

这在语法上是无效的。您注释掉的代码通常可以保护您免受这种情况的影响,因为如果没有参数,它会导致脚本退出。

这就是为什么您应该始终引用变量,例如:

if [ "" == "a" ]; 

即使 </code> 未定义,这也会正确计算。</p> <p>如果您正在为 bash 编写脚本,您可以利用 <code>[[ ... ]] 表达式,它与 [ ... ] 非常相似,但不需要同样注意引号。如果你要写:

if [[  == "a" ]];

它会如愿以偿。 zsh 可能有类似的东西,但我不确定。