我们可以使用bash -n script.sh来验证shell脚本的语法.但是,当我尝试测试此函数时,我注意到此选项无法找到所有语法错误.
例如:
root@ubuntu:~/testenv# cat test
#!/bin/bash
SEND=1
if [ "$SEND" -eq 0 ]
echo no
fi
现在,让我们测试脚本:
root@ubuntu:~/testenv# bash -n test
test: line 5: Syntax error near unexpected token `fi'
test: line 5: `fi'
root@ubuntu:~/testenv# cat test
#!/bin/bash
SEND=1
if [ "$SEND" -eq 0
then
echo no
fi
root@ubuntu:~/testenv# bash -n test
root@ubuntu:~/testenv#
没啥事儿!
我还检查了bash的手册页,它描述了“-n”是:
-n Read commands but do not execute them. This may be used to check a
shell script for Syntax errors. This is ignored by interactive
shells.
它是一个脚本文件,所以它不应该是一个“交互式shell”吧?那么,这怎么可能发生呢?
解决方法:
我猜你已经遇到了一个非常奇怪的shell实现单括号条件的方式:[是一个命令,而不是一个特殊字符.查看系统可执行文件目录(可能是/usr/bin),您将找到一个名为[实现此命令的文件]的可执行文件.当你写的东西像
[ "$SEND" -eq 0 ]
那么你实际上是在调用命令[有四个参数:
> $SEND的价值
>字符串-eq
>字符串0
>字符串]
命令[检查最后一个参数是否为(因为否则看起来很奇怪),然后将剩余的参数放在一起形成一个条件并返回测试条件的结果.
现在,因为[是一个命令,用你喜欢的任何参数集调用该命令不是语法错误.当然,如果你不使用尾随],你将收到一个错误,但该错误来自命令[,而不是来自shell.这意味着您必须实际运行脚本才能获得错误 – 语法检查器不会看到任何错误.就bash而言,[只是一个命令名称,与my_custom_conditional_test没有区别,如果你要写的话
my_custom_conditional_test "$SEND" -eq 0
很明显这很好,对吗?巴什认为[同样的方式.
我应该注意,为了提高效率,bash实际上并没有使用可执行文件/usr/bin/[;它有自己的内置实现[.但人们期望[无论是否内置于shell中,都采用相同的方式行事,因此Bash语法检查程序无法自行处理[特殊处理.由于调用/usr/bin/[没有尾随]不会是语法错误,因此调用内置函数[没有]时不会出现语法错误.
你可以将它与[[,它或多或少地做同样的事情(测试一个条件))进行对比,但shell给出了特殊含义. [[是shell语法中的特殊标记,而不是命令.如果你写[[而不是[,你省略相应的尾随]],你打赌Bash会抱怨语法错误.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。