Answers:
bash -n scriptname
也许是一个明显的警告:这可以验证语法,但不会检查您的bash脚本是否尝试执行不在您的路径中的命令(例如ech hello
而不是)echo hello
。
set
做的单字符选项。
if ["$var" == "string" ]
不是if [ "$var" == "string" ]
type [
说“ [是内置的shell”。它最终将委派给该test
程序,但也期望将其括起来。因此,它就像if test"$var"
,不是作者的意思,而是在语法上有效的(例如$ var的值为“ a”,那么我们将看到“ bash:testa:未找到命令”)。要点是,从语法上讲,没有缺少空间。
[
在这种情况下,只有在$var
碰巧扩展为空字符串时才调用Builtin 。如果$var
扩展到非空字符串,[
是串联与字符串被解释为一个命令名称(而不是函数被Bash,是的,就是名字)语法上有效的,但是,当你的状态,显然不是意图。如果您使用[[
而不是[
,即使[[
是shell 关键字(而不是内置关键字),您也会得到相同的结果,因为意外的字符串连接仍然会覆盖关键字的识别。
["$var"
是 语法上有效的命令名称表达; 同样,令牌==
和"$string"
是有效的命令参数。(通常,内置[
进行解析命令的语法,而[[
-作为一个壳的关键字 -被分析是不同的。)的外壳内置[
并没有 委托给“ test
程序”(外部工具): ,bash
,,dash
都具有内置的两个版本和ksh
zsh
[
test
,并且不称其为外部公用事业公司。
时间改变了一切。这是一个提供Shell脚本在线语法检查的网站。
我发现检测常见错误非常强大。
ShellCheck是用于sh / bash脚本的静态分析和整理工具。它主要侧重于处理典型的初学者和中级语法错误和陷阱,在这些错误和陷阱中,shell仅仅给出了隐秘的错误消息或奇怪的行为,但它还报告了一些更高级的问题,在某些极端情况下,情况可能会导致延迟失败。
Haskell源代码可在GitHub上获得!
apt-get install shellcheck
trusty-backports
。
我还会在我编写的每个bash脚本上启用'u'选项,以进行一些额外的检查:
set -u
这将报告未初始化变量的用法,例如以下脚本“ check_init.sh”
#!/bin/sh
set -u
message=hello
echo $mesage
运行脚本:
$ check_init.sh
将报告以下内容:
./check_init.sh[4]:消息:未设置参数。
捕捉错别字非常有用
set -u
尽管这并不能真正回答问题,因为您必须运行脚本来获取错误消息。甚至没有bash -n check_init.sh
显示该警告
sh -n script-name
运行这个。如果脚本中有任何语法错误,则它将返回相同的错误消息。如果没有错误,则显示出来时不会给出任何消息。您可以使用立即检查echo $?
,它将返回0
确认成功而没有任何错误。
它对我很好。我在Linux OS Bash Shell上运行。
sh -n
可能不会检查该脚本是否是有效的Bash脚本。它可能会带来假阴性。sh
是一些Bourne shell变体,通常不是Bash。例如,在Ubuntu Linux中realpath -e $(command -v sh)
,/ bin / dash
有用于IntelliJ IDEA的BashSupport插件,用于检查语法。
.sh
以Bash脚本结尾或与Bash脚本相关联的其他扩展名不起作用,那么使用某些模板工具(例如ERB)生成脚本的情况就是这样(然后它们以结尾.erb
)。如果您要解决此问题,请投票给youtrack.jetbrains.com/issue/IDEA-79574!
如果在变量中需要目录中所有文件的有效性(git pre-commit钩子,构建lint脚本),则可以捕获“ sh -n”或“ bash -n”命令的stderr输出(请参见其他答案)中的变量,并根据该变量得出“ if / else”
bashErrLines=$(find bin/ -type f -name '*.sh' -exec sh -n {} \; 2>&1 > /dev/null)
if [ "$bashErrLines" != "" ]; then
# at least one sh file in the bin dir has a syntax error
echo $bashErrLines;
exit;
fi
根据需要将“ sh”更改为“ bash”