linux bash语法检查,关于linux:如何在不运行Bash脚本的情况下进行语法检查?

是否可以不执行而检查bash脚本语法?

使用Perl,我可以运行perl -c 'script name'。 bash脚本有任何等效命令吗?

相关:是否有像Shell一样的Lint或Perl :: Critic等静态分析工具?

bash -n scriptname

也许是一个明显的警告:这可以验证语法,但不会检查bash脚本是否尝试执行不在路径中的命令,例如ech hello而不是echo hello。

感谢您的提示,我一定会使用这个提示。奇怪的是,此选项未在bash手册页中列出:S ...

在bash的联机帮助页的" SHELL BUILTIN COMMANDS / set"下,记录了-n,并且在联机帮助页的开头,bash解释了set的所有单字符选项。

给(对我而言)不明显的警告,它也不会捕获由缺少空格if ["$var" =="string" ]而不是if ["$var" =="string" ]引起的错误

@Brynjar那是因为它只是语法检查。开括号不是语法,那就是要运行的函数的名称。 type [说" [是内置的shell"。它最终将委托给test程序,但也希望将其括起来。因此它类似于if test"$var",这不是作者的意思,但是在语法上有效(例如$ var的值为" a",那么我们将看到" bash:testa:未找到命令")。要点是,从语法上讲,没有缺少空间。

@JoshuaCheek:在这种情况下,仅当$var恰好扩展为空字符串时才调用内置[。如果$var扩展为非空字符串,则[与该字符串连接,并且被Bash解释为命令名(不是函数名),是的,在语法上是有效的,但是如您所述,显然不是目的。如果使用[[而不是[,即使[[是shell关键字(而不是内置关键字),您也会得到相同的结果,因为意外的字符串连接仍然会覆盖对关键字的识别。

@JoshuaCheek:Bash仍在这里进行语法检查:其检查的简单命令调用语法:["$var"在语法上是有效的命令名称表达式;同样,标记==和"$string"是有效的命令参数。 (通常,内置的[是用命令语法解析的,而[[-作为shell关键字-的解析方式是不同的。)shell内置的[不会委派给" test程序"(外部实用程序): bash,dash,ksh,zsh都具有[和test的内置版本,并且它们不调用其外部公用程序。

底线是:仅使用Bash本身,-n是您的最佳选择,但这不会引起许多初学者可能犯的错误;要捕获这些错误,请使用shellcheck.net或其CLI(如dvd818s答案中所述)。

@ mklement0很好,非常感谢您的解释!

另一个警告:不会考虑脚本中设置的选项。例如,如果添加shopt -s extglob,然后在case中执行foo@(bar|baz)),则bash -n将看到语法错误(bash -s extglob -n不会,但您永远不知道脚本的哪一部分受到影响)

@AloisMahdal不幸的是,在一般情况下这是不可能解决的,因为shell选项可以更改中间脚本,甚至可以基于只能在运行时知道的信息进行更改。

以下是man bash中的文档:-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.

是-n选项版本或特定于os的;在osx上似乎不起作用

时间改变了一切。这是一个提供Shell脚本在线语法检查的网站。

我发现检测常见错误非常强大。

0786ff385dac5bd1fba5853b13fa52fd.png

关于ShellCheck

ShellCheck是用于sh / bash脚本的静态分析和整理工具。它主要专注于处理典型的初学者和中级语法错误和陷阱,在这些错误和陷阱中,shell仅仅给出神秘的错误消息或奇怪的行为,但它还报告了一些更高级的问题,在某些极端情况下,情况可能会导致延迟失败。

Haskell源代码可在GitHub上获得!

大提示;在OSX上,您现在还可以通过Homebrew:brew install shellcheck安装shellcheck.net CLI shellcheck。

也在debian&friends上:apt-get install shellcheck

对于可信任的Ubuntu,必须从trusty-backports安装此软件包。

这应该是公认的答案!

如上所述,需要信任依赖关系,可以按照以下说明在ubuntu 14.04中安装它:sudo apt-get -f install,然后:sudo sudo apt-get install shellcheck

这确实很有用,但是它不使用Bash的解析器,而是使用它自己的解析器。在大多数情况下,这已经足够好了,它可以识别解析问题和其他问题,但是至少有一种极端的情况(可能还有其他我未曾见过的情况)无法以完全相同的方式进行解析。

我还会在我编写的每个bash脚本上启用'u'选项,以进行一些额外的检查:

set -u

这将报告未初始化变量的用法,例如以下脚本" check_init.sh"

#!/bin/sh

set -u

message=hello

echo $mesage

运行脚本:

$check_init.sh

将报告以下内容:

./check_init.sh[4]: mesage: Parameter not set.

捕捉错别字非常有用

我总是在我的bash脚本中设置这些标志,如果通过这些标志,则最好设置" set -o errexit"" set -o nounset"" set -o pipefail"

为set -u +1,尽管这不能真正回答问题,因为您必须运行脚本来获取错误消息。甚至bash -n check_init.sh都没有显示警告

sh  -n   script-name

运行这个。如果脚本中有任何语法错误,则它将返回相同的错误消息。

如果没有错误,则显示出来时不会给出任何消息。您可以使用echo $?立即进行检查,这将返回0并确认成功,没有任何错误。

它对我很好。我在Linux OS Bash Shell上运行。

+1用于返回值检查。

尽管与bash语法检查不完全相关-使用set -x和set + x调试整个脚本或脚本的各个部分非常有用

谢谢你,这不知道-n,但是我想要的是@GuruM> sh -x test.sh,因为它显示了脚本的生成输出

是。我忘了提到您可以在命令行上执行以下操作:1)bash -x test.sh#这将在调试模式下运行整个脚本2)设置+ x; bash test.sh; set -x#在脚本运行之前/之后设置调试模式开/关在脚本中:a)#!/ bin / bash -x#在脚本顶部添加调试模式b)设置+ x;码; set -x#为脚本的任何部分添加调试模式

我实际上检查了当前目录中的所有bash脚本是否存在语法错误,而无需使用find工具运行它们:

例:

find . -name '*.sh' -exec bash -n {} \;

如果要将其用于单个文件,只需使用文件名编辑通配符。

空命令[冒号]在调试以查看变量的值时也很有用

set -x

for i in {1..10}; do

let i=i+1

: i=$i

done

set -

这是如何运作的?

它使用参数扩展

这行得通,因为set -x在执行之前显示每一行

如果在变量中需要目录中所有文件的有效性(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"

有用于IntelliJ IDEA的BashSupport插件,用于检查语法。

但是,如果文件不以.sh或与Bash脚本相关联的其他扩展名结尾,则将无法正常工作,如果您使用诸如ERB的模板工具生成脚本(则它们以.erb结尾),情况就是如此。如果您要解决此问题,请投票给youtrack.jetbrains.com/issue/IDEA-79574!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值