shellcheck 是一款实用的 shell脚本静态检查工具。
首先,可以帮助你提前发现并修复简单的语法错误,节约时间。每次都需要运行才发现写错了一个小地方,确实非常浪费时间。
其次,可以针对你当前不够完善不够健壮的写法,提供建议,帮助你提前绕开一些坑,避免等问题真的发生了才去调试处理。
在其介绍中,目标是针对所有用户的,从初学者到高手,都用得上
指出并澄清典型的初学者的语法问题,那通常会shell提供神秘的错误消息。
指出并澄清典型的中级的语义问题,这些问题会导致shell出现奇怪且反直觉的行为。
指出可能导致高级用户的脚本中,可能在未来某种情况下失败的陷阱。
如何使用 在网页上使用非常简单,在网页 https://www.shellcheck.net 上,贴入你的脚本,运行检查即可
在命令行中使用下载后,在命令行中调用 shellcheck yourscript 即可
集成到编辑器中(推荐)推荐将shellcheck直接集成到日常编辑器中,这样就可以直接在编辑器中查看ShellCheck建议,以最快速度发现并修复问题。
Vim 通过 ALE, Neomake 或 Syntastic 进行集成
Emacs 通过 Flycheck 或 Flymake 集成
Sublime 通过 SublimeLinter.
Atom 通过 Linter.
VSCode 通过 vscode-shellcheck.
安装方式在大多数发行版的包管理中,已经有shellcheck了,如在基于debian的机器上
apt-get install shellcheck其他系统的具体安装方式,可以查阅 shellcheck 的github首页介绍
当然,也可以选择自行从源码安装。
问题列表那么shellcheck具体会检查一些什么问题呢,以下给出一个不完整的问题检查列表。
可以看下,你是否都能意识到这样的写法时有错误或隐患的。
如果发现有自己不知道的或自己容易错漏的,那么也许你也应该花点时间,装上shellcheck。
ShellCheck 可以识别大多数不正确的条件判断语句
[[ n != 0 ]] # Constant test expressions # 常量测试表达式 [[ -e *.mpg ]] # Existence checks of globs # 对文件是否存在进行检查时,使用通配符 [[ $foo==0 ]] # Always true due to missing spaces #由于缺乏空格,结果总是为真 [[ -n "$foo " ]] # Always true due to literals #由于字面值存在,结果总是为真 [[ $foo =~ "fo+" ]] # Quoted regex in =~ # 在 =~ 中使用正则表达式 [ foo =~ re ] # Unsupported [ ] operators # 不支持的[]运算符 [ $1 -eq "shellcheck" ] # Numerical comparison of strings # 比较数字和字符串 [ $n && $m ] # && in [ .. ] # 在[]中使用&&运算符 [ grep -q foo file ] # Command without $(..) #命令缺少了$(..) [[ "$$file" == *.jpg ]] # Comparisons that can't succeed #无法成功的比较 (( 1 -lt 2 )) # Using test operators in ((..)) #在((..))中使用比较 常见的对命令的错误使用ShellCheck 可以识别对一些命令的错误使用
grep '*foo*' file # Globs in regex contexts #在grep的正则表达式中前后使用通配符 find . -exec foo {} && bar {} \; # Prematurely terminated find -exec # 使find -exec 过早结束 sudo echo 'Var=42' > /etc/profile # Redirecting sudo # 重定向sudo time --format=%s sleep 10 # Passing time(1) flags to time builtin # 将time(1)的标志传递给内建的time while read h; do ssh "$h" uptime # Commands eating while loop input # 一个获取输入的while循环中,使用同样会获取输入的命令 alias archive='mv $1 /backup' # Defining aliases with arguments # 定义使用参数的alias tr -cd '[a-zA-Z0-9]' # [] around ranges in tr # 在tr的参数范围外使用[] exec foo; echo "Done!" # Misused 'exec' # 错误地使用exec find -name \*.bak -o -name \*~ -delete # Implicit precedence in find # 在find中的隐式优先级 # find . -exec foo > bar \; # Redirections in find #find中的重定向 f() { whoami; }; sudo f # External use of internal functions #在外部使用内部函数 初学者的常见错误ShellCheck 识别很多初学者的语法错误
var = 42 # Spaces around = in assignments #等号两边的空格 $foo=42 # $ in assignments # 对变量赋值时使用了$ for $var in *; do ... # $ in for loop variables # 在循环变量处使用$ var$n="Hello" # Wrong indirect assignment #错误的变量 echo ${var$n} # Wrong indirect reference #错误的引用 var=(1, 2, 3) # Comma separated arrays #逗号分割数组 array=( [index] = value ) # Incorrect index initialization #错误的索引初始化 echo $var[14] # Missing {} in array references #引用数组缺少{} echo "Argument 10 is $10" # Positional parameter misreference #错误的位置参数引用 if $(myfunction); then ..; fi # Wrapping commands in $() #在命令外加上$() else if othercondition; then .. # Using 'else if' #使用else if f; f() { echo "hello world; } # Using function before definition 在函数定义之前使用函数 [ false ] # 'false' being true # 此处false为true if ( -f file ) # Using (..) instead of test #使用()取代测试条件 风格