ShellCheck是一个GPLv3工具,为bash/sh shell脚本提供警告和建议:
ShellCheck的目标是
-
指出并澄清导致shell的典型初学者语法问题给出隐秘的错误消息。
-
指出并澄清典型的中级语义问题使壳表现出奇怪和反直觉的行为。
-
指出可能导致高级用户的其他工作脚本在未来的情况下会失败。
请参见坏代码库有关ShellCheck可以帮助您识别的内容的示例!
目录
如何使用
有很多方法可以使用ShellCheck!
在网络上
将shell脚本粘贴到https://www.shellcheck.net以获得即时反馈。
ShellCheck.net始终与最新的git提交同步,这是让ShellCheck运行的最简单方法。告诉你的朋友!
从您的终端
运行shell检查脚本
如上图所示,在终端中进行即时输出。
在您的编辑器中
您可以在各种编辑器中直接查看ShellCheck建议。
.
.
在您的构建或测试套件中
虽然ShellCheck主要用于交互式使用,但它可以很容易地添加到构建或测试套件中。它规范地使用退出代码,因此您只需添加一个检查外壳
命令作为过程的一部分。
例如,在Makefile中:
检查脚本:#如果这些文件中有任何文件出现警告,则失败shellcheck myscripts/*.sh
或在Travis CI中.travis.yml文件
文件:
脚本:#如果这些文件中有任何文件出现警告,则失败-shellcheck myscripts/*.sh
预先安装了ShellCheck并准备使用的服务和平台:
大多数其他服务,包括GitLab公司,让您安装Shell通过系统的包管理器检查您自己(请参阅正在安装),或通过下载和解压缩二进制释放.
不管怎样,最好手动安装特定的ShellCheck版本。这样可以避免当发布带有新警告的新版本时,任何意外构建都会中断。
对于自定义筛选或报告,ShellCheck可以输出简单的JSON、CheckStyle兼容的XML、,GCC兼容警告以及人类可读文本(有或没有ANSI颜色)。请参阅集成更多文档的wiki页面。
正在安装
本地安装ShellCheck的最简单方法是通过包管理器。
在带有Cabal的系统上(安装到~/.电缆/箱子
):
阴谋集团更新阴谋集团安装ShellCheck
在带有Stack的系统上(安装到~/.本地/bin
):
堆栈更新堆栈安装ShellCheck
在基于Debian的发行版上:
sudo apt安装shellcheck
在基于Arch Linux的发行版上:
pacman-S外壳检查
或者消除依赖性贝壳检查箱平均零售价。
在基于Gentoo的发行版上:
出现--询问shellcheck
在基于EPEL的发行版上:
sudo yum-y安装epel-releasesudo yum安装ShellCheck
在基于Fedora的发行版上:
dnf安装ShellCheck
在FreeBSD上:
pkg安装hs-ShellCheck
在带有Homebrew的macOS(OS X)上:
brew安装shellcheck
或使用MacPorts:
sudo端口安装shellcheck
在OpenBSD上:
pkg_添加shellcheck
在openSUSE上
ShellCheck中的zypper
或使用OneClickInstall-https://software.opensuse.org/package/ShellCheck网站
关于索卢斯:
eopkg安装shellcheck
在Windows上(通过巧克力色的):
C: \>巧克力安装shellcheck
或Windows(通过有翼的):
C: \>winget安装--id koalaman.shellcheck
或Windows(通过铲):
C: \>勺子安装外壳检查
发件人康达锻造厂:
conda安装-c conda-forge外壳检查
从快照存储:
快速安装--通道=边缘外壳检查
来自Docker Hub:
docker运行--rm-v“$PWD:/mnt”koalaman/shellcheck:stable myscript#或:该版本的v0.4.7,或:每日构建的最新版本
或使用考拉曼/阿尔卑斯山贝壳
如果您想扩展一个更大的基于Alpine Linux的映像。它的工作方式与常规的Alpine图像完全相同,但已预先安装shellcheck。
使用nix包管理器:
nix-env-iA nixpkgs.shellcheck
或者,您可以在此处下载最新版本的预编译二进制文件:
或查看GitHub发布对于其他版本(包括最新的每日git构建的meta-release)。
目前Apple Silicon没有官方二进制文件,但第三方版本可以通过Visual Studio代码的ShellCheck.
分发包已经附带了男人
第页。如果您是从源代码进行构建,则可以使用以下组件进行安装:
pandoc-s-f markdown-smart-t-man shellcheck.1.md-o shellcheck。1sudo mv shellcheck.1/usr/share/man/man1
预先提交
要通过运行ShellCheck预先提交,将挂钩添加到您的.预提交配置.yaml
:
回购:-回购:https://github.com/koalaman/shellcheck预提交修订版:v0.7.2挂钩:-id:外壳检查#args:[“--severty=warning”]#可选仅显示错误和警告
特拉维斯CI
Travis CI现在默认集成了ShellCheck,因此无需手动安装。
如果您仍然想这样做,以便在空闲时升级或确保使用最新版本,按照以下步骤安装二进制版本。
安装预编译的二进制文件
预编译的二进制文件进来了焦油.xz
文件。要解压缩它们,请确保x赫兹
已安装。在Debian/Ubuntu/Mint上,您可以apt安装xz-utils
.在Redhat/Fedora/CentOS上,yum-y安装xz
.
一个简单的安装程序可以执行以下操作:
scversion=“stable”#或“v0.4.7”,或“latest”wget-qO“https://github.com/koalaman/shellcheck/releases/下载/${scversion?}/shellcheck-${sc版本?}.linux.x86_64.tar.xz“|tar-xJvcp“shellcheck-${scversion}/shellcheck”/usr/bin/shellcheck--版本
从源代码编译
本节介绍如何从源目录构建ShellCheck。ShellCheck是用Haskell编写的,需要2GB的RAM才能编译。
安装电缆
ShellCheck是使用Cabal构建和打包的。安装软件包电缆安装
从系统的包管理器(例如。适配基
,酿造
,浮现
,百胜
,或发酵剂
).
在macOS(OSX)上,您可以使用brew快速安装Cabal,如果您尝试从源代码编译它,则需要几分钟而不是30多分钟。
$brew安装cabal-install
在MacPorts上,该包被称为hs-cabal安装
,而本地Windows用户应该从安装Haskell平台的最新版本https://www.haskell.org/platform网站/
验证阴谋集团
已安装并用更新其依赖项列表
$cabal更新
编译ShellCheck
git克隆
此存储库,以及光盘
要编译/安装的ShellCheck源目录:
$cabal安装
这将编译ShellCheck并将其安装到您的~/.电缆/箱子
目录。
将此目录添加到您的路径
(对于bash,将此添加到您的~/.bashrc
):
export PATH=“$HOME/.cabal/bin:$PATH”
注销并再次登录,验证PATH设置是否正确:
$哪张壳支票~/.电缆/箱子/外壳检查
在本机Windows上路径
应该已经设置,但系统可能使用旧代码页。在命令提示符
,父进程
和Powershell ISE,确保使用TrueType字体,而不是光栅字体,并将代码页到UTF-8(65001)chcp公司
:
chcp 65001型
在Powershell ISE中,您可能需要额外更新输出编码:
[控制台]::OutputEncoding=[System.Text.Encoding]::UTF8
运行测试
要运行单元测试套件:
$cabal测试
错误代码库
那么ShellCheck寻找什么样的东西呢?以下是检测到的问题的不完整列表。
报价
ShellCheck可以识别几种类型的错误引用:
echo$1#未引用变量找到-name*.ogg#未引用的查找/grep模式rm“~/my file.txt”#带引号的波浪号扩展v='--verbose=“true”';cmd$v#变量中的文字引号“*.ogg”中的for f#引用错误的“for”循环触摸$@#未报价$@echo“别忘了重启!”#单引号以撇号结束echo“不要在家里尝试”#试图在“”中逃跑echo“Path is$Path”#单引号中的变量trap“回声${秒}s“0#过早扩张陷阱unset var[i]#数组索引被视为glob
条件
ShellCheck可以识别许多类型的错误测试语句。
[[n!=0]]#常量测试表达式[[-e*.mpg]]#全局变量的存在性检查[[$foo==0]]#由于缺少空格而始终为true[[-n“$foo”]]#由于文字而始终为true[[$foo=~“fo+”]]#中引用的regex=~[foo=~re]#不支持的[]运算符[$1-eq“shellcheck”]#字符串的数值比较[$n&&$m]#&&在[..]中[grep-q foo file]#不带$(..)的命令[[“$$file”==*.jpg]]#无法成功的比较((1-lt 2))#在((..))中使用测试运算符[x]&[y]|[z]#意外接地和管道
经常误用的命令
ShellCheck可以识别错误使用命令的实例:
grep“*foo*”文件#regex上下文中的Globs找到-执行foo{}&bar{}\;#提前终止的find-execsudo-echo'Var=42'>/etc/profile#重定向sudotime--format=%s sleep 10#将时间(1)标志传递给时间内置读取h时;do ssh“$h”uptime#循环输入时执行命令alias archive='mv$1/backup'#使用参数定义别名tr-cd'[a-zA-Z0-9]'#[]围绕tr中的范围执行foo;echo“完成!”#误用了“exec”find-name \*.bak-o-name \*~-delete#查找中的隐式优先级#找到-exec foo>bar \;#查找中的重定向f(){whoami;};sudo f#内部函数的外部使用
初学者常见错误
ShellCheck识别许多常见的初学者语法错误:
var=42#赋值中的空格=分配中$foo=42#$对于*中的$var;执行…#$in for循环变量var$n=“Hello”#错误的间接赋值echo${var$n}#错误的间接引用var=(1,2,3)#逗号分隔的数组array=([index]=value)#索引初始化不正确echo$var[14]#数组引用中缺少{}echo“参数10是$10”#位置参数错误引用如果$(myfunction);然后。。;fi#在$()中包装命令其他情况下;然后…#使用“else if”f;f(){echo“hello world;}#定义前使用函数[false]#“false”为trueif(-f文件)#使用(..)代替测试
样式
ShellCheck可以提出改进风格的建议:
[[-z$(find/tmp|grep-mpg)]]#改用grep-qa>>日志;b>>对数;c>>log#改用重定向块echo“The time is `date`”#改用$()cd目录;过程*;光盘..;#改用子壳echo$[1+2]#使用标准$((..))而不是旧的$[]echo$(($RANDOM%6))#不要在$((..))中的变量上使用$echo“$(date)”#无用的echo用法cat file|grep foo#无用的cat用法
数据和键入错误
ShellCheck可以识别与数据和键入相关的问题:
args=“$@”#将数组分配给字符串文件=(foo bar);echo“$files”#将数组引用为字符串declare-A arr=(foo bar)#没有索引的关联数组printf“%s\n”“参数:$@.”#串联字符串和数组[[$#>2]]#将数字作为字符串进行比较var=世界;echo“Hello”var#未使用的小写变量echo“Hello$name”#未分配的小写变量cmd |读取栏;echo$bar#子shell中的赋值cat foo|cp bar#管道连接到不读取的命令printf“%s:%s\n”foo#printf参数计数不匹配eval“${array[@]}”#数组eval中的单词边界丢失对于“${x[@]}”中的i;do${x[$i]}#使用数组值作为键
稳健性
ShellCheck可以为提高脚本的健壮性提供建议:
rm-rf“$STEAMROOT/”*#灾难性rm触摸/-l;ls*#可能成为选项的球找到-exec sh-c'a&&b{}'\;#查找-exec shell注入printf“Hello$name”#printf格式的变量对于$(ls*.txt)中的f;do#迭代ls输出export MYVAR=$(cmd)#屏蔽的退出代码2.*):;;中的case$版本;;2.6.*)#阴影案例分支
便携性
当使用shebang不支持的功能时,ShellCheck将发出警告。例如,如果将shebang设置为#!/垃圾桶/桶
,ShellCheck将发出有关可移植性问题的警告,类似于反支票主义
:
echo{1..$n}#在ksh中有效,但在bash/dash/sh中无效echo{1..10}#适用于ksh和bash,但不适用于dash/shecho-n 42#在ksh、bash和dash中工作,在sh中未定义expr match str regex#“expr str:regex”的不可移植别名`trap“exit 42”sigint#不可移植的信号规范cmd&>file#不可移植的重定向运算符读取foo</dev/tcp/host/22#不可移植的截获文件foo-bar(){..;}#未定义/不支持的函数名[$UID=0]#短划线/sh中未定义变量local var=value#本地在sh中未定义time sleep 1 | sleep 5#“时间”的未定义用法
其他
ShellCheck发现了一系列其他问题:
PS1='\e[0;32m\$\e[0m'#PS1颜色不在\[..\]中PATH=“$PATH:~/bin”#$PATH中的文字波浪号rm“file”#Unicode引号echo“Hello world”#回车/DOS行尾echo hello \#后面的空格\var=42 echo$var#内联环境扩展!# bin/bash-x-e#常见shebang错误echo$((n/180*100))#不必要的精度损失ls*[:digit:].txt#错误的字符类globssed的/foo/bar/文件>文件#重定向到输入var2=$var2#分配给自身的变量[x$var=xval]#过时的x比较ls(){ls-l“$@”;}#无限递归包装器别名ls='ls-l';ls foo#生效前使用的别名对于x;对x执行do;do#嵌套循环使用相同的变量而getopts“a”f;do case$f in“b”)#未处理的getopts标志
证词
起初你会说“shellcheck很棒”,但后来你会说:“我们还在使用bash吗?”
亚历山大·塔拉西科夫,通过推特
忽略问题
可以通过环境变量、命令行在文件中单独或全局忽略问题:
https://github.com/koalaman/shellcheck/wiki/忽略
报告Bug
请使用GitHub问题跟踪器查找任何错误或功能建议:
https://github.com/koalaman/shellcheck/issues
贡献
请按照GitHub拉取请求提交代码或文档的补丁程序!检查退出开发指南上ShellCheck Wiki。
捐款必须根据GNU GPLv3获得许可。投稿人保留版权。
版权
ShellCheck是根据GNU通用公共许可证v3进行许可的。文件中包含此许可证的副本许可证.
版权所有2012-2019,维达尔“koala_man”霍伦和贡献者。
检查壳快乐!
其他资源