sh/Bash脚本静态分析和lint工具:ShellCheck

jopen 10年前

sh/Bash脚本静态分析和lint工具:ShellCheck。它不仅主要关注shell脚本典型初中级语法错误和shell输出的神秘的错误信息或者奇怪行为的缺陷,也能报告一些高级导致后来故障的高级问题。
terminal.png

What does ShellCheck check?

Here is an incomplete list of things ShellCheck warns about and suggests improvements to:

Unquoted globs for find/grep
find . -name *.ogg
</div>
Constant test expressions
[[ n != 0 ]]
</div>
Assigning arrays to strings
args="$@"
</div>
Redirecting into source file
sed -e 's/foo/bar/g' file > file
</div>
Existence checks of globs
[[ -e *.mpg ]]
</div>
Globs in regex context
grep '*foo*' file
</div>
PS1 colors not in \[..\]
PS1='\e[0;32m\$\e[0m '
</div>
Prematurely terminated find -exec
find / -exec touch {} && echo {} \;
</div>
Literal quotes in arguments
verbose='--verbose="true"' cmd $verbose
</div>
Assignment in subshells
echo foo | read bar  echo $bar
</div>
Confusing time(1) for builtin
time --format=%s sleep 10
</div>
~ in quotes
rm "~/my file.txt"
</div>
Single, quoted 'for' argument
for f in "*.ogg" do rm $f; done
</div>
Arithmetic truncation
echo $((n/180*100))
</div>
Functions used externally
f() { rm file; }; sudo f
</div>
Unused variables
var=World; echo "Hello " var
</div>
Looping over ls output
for f in $(ls *.ogg) do ...; done
</div>
Arguments in aliases
alias archive='mv $1 /backup'
</div>
Referencing arrays as strings
files=(foo bar); echo "$files"
</div>
Unquoted command expansion
tar cf file$(date).tar dir
</div>
$ in for loop variables
for $var in foo bar baz; do echo "$var"; done
</div>
Unquoted $@
touch $@
</div>
Unicode quotes
rm file
</div>
Attempted redirection of stdout+stderr
cmd 2>&1 > /dev/null
</div>
Attempted indirect assignment
var$n="Hello"
</div>
Attempted indirect reference
echo ${var$n}
</div>
Variables in single quotes
echo 'Path is $PATH'
</div>
Comparing numbers with < or >
[[ $n > 0 ]]
</div>
Unsupported [ ] operators
[ foo =~ re ]
</div>
Using ~ in $PATH
PATH="$PATH:~/bin"
</div>
Quoted =~ regex
[[ $foo =~ "fo+" ]]
</div>
Opportunities for grep -q
[[ -z $(find /tmp | grep mpg) ]]
</div>
Tautology due to spacing
[[ $foo==0 ]]
</div>
Variable brace expansion (Bash)
echo {1..$n}
</div>
Commands eating loop input
while read host; do ssh "$host" uptime; done < file
</div>
Decimals arithmetics
echo $((3.14*r*r))
</div>
Comma separated arrays
var=(1, 2, 3)
</div>
Misused 'exec'
exec foo; echo "Done!"
</div>
Globs that could become options
touch ./-l; ls *
</div>
Common shebang errors
#!/bin/bash -x -e
</div>
Variables in printf format
printf "Hello $name"
</div>
Numerical comparison of strings
[[ $1 -eq "shellcheck" ]]
</div>
Prefix assignments in args
var=42 echo $var
</div>
Implicit precedence in find
find . -name '*.bak' -o -name '*~' -delete
</div>
Useless use of echo
echo $(date)
</div>
Repetitive redirections
cmd1 >> file; cmd2 >> file; cmd3 >> file;
</div>
Redirecting sudo
sudo echo 'alias sl=ls' >> /etc/profile
</div>
[] around ranges in tr
tr '[a-z]' '[A-Z]'
</div>
Misquoted traps
trap "echo \"Runtime: ${SECONDS}s\"" exit
</div>
&& in [ .. ]
[ $n && $m ]
</div>
Singlequote closed by apostrophe
echo 'Don't forget to run foo --update!'
</div>
Attempting to escape ' in ''
var='Don\'t try this at home'
</div>
Misused char class globs
ls *[:digit:].txt
</div>
Concatenating strings and arrays.
printf "%s\n" "Command line was $@."
</div>
Positional parameter misreference
echo "Argument 10 is $10"
</div>
cd-and-back antipattern
for d in *; do cd "$d"; cmd; cd ..; done
</div>
Missing semicolons in loops
for f in *.mp3 do true; done
</div>
$ in assignments
$foo=42
</div>
Aliases expanding early
alias whereami="echo $PWD"
</div>
Spaces in assignment
var = 42
</div>
Features shebang may not support
#!/bin/sh echo {1..10}
</div>
Spurious $()/``
cmd='echo foo'; `$cmd`;
</div>

项目主页:http://www.open-open.com/lib/view/home/1419234081734