
ShellCheck: a static analysis and linting tool for sh/bash scripts - pmoriarty
http://www.shellcheck.net/about.html
======
SwellJoe
I still write and maintain a surprisingly large amount of sh code (it used to
be bash, but when Ubuntu switched to defaulting to ash, I had to remove the
bashisms). Sometimes a shell script is still the shortest line from point A to
point B, and it's always there.

But, whenever I work on that code after a long time of not reading it, I'm
always afraid I'm breaking something, introducing new bashisms, etc. and have
to test it thoroughly across multiple systems to be sure I didn't break
something. There is checkbashisms which catches most bashisms, but there's
still a lot of weird stuff in shell scripts, and without block or function
scope it can be challenging to stay on top of a large shell codebase.

In short, I've been working on more automatic testing (i.e. tests without
explicitly written unit tests) of my code lately, and the shell stuff is
pretty hard to do that for, compared to Perl and JavaScript. So, this is
probably awesome.

~~~
uaygsfdbzf
What are you using for Perl and JavaScript?

~~~
SwellJoe
I'm still working on it, but Perl::Critic is good (I've been using it in vim
for a while, which checks every time you save), strict and warnings is good
(which would be enabled on any new Perl program, but I'm working with a 15
year old codebase, so enabling these automatically creates a bunch of new
failing "tests" that need fixing). There's a few different ways to use
Perl::Critic in tests, the most promising seems to be
Test::Perl::Critic::Progressive, which allows gradual introduction of Critic-
friendly code without turning your whole smoker page red. (Which for me, is a
problem...we'd have hundreds of failing tests, which would be overwhelming and
make it hard to spot tests that will affect users.)

Devel::NYTProf is great for spotting performance regressions.

And, since we're pushing out HTML as the result of our application scripts
running, I've been working on integrating HTML::Lint (I had to patch it to
allow HTML::Pluggable::HTML5 to work, but I've sent a pull request to Andy, so
the next version will likely support HTML5) into our test suite. This will
tell us if any script breaks in such a way that it produces invalid HTML.

For JavaScript, jslint and jshint exist. I haven't started integrating or
experimenting with either, yet. Our JavaScript is pretty minimal at the moment
(a few thousand lines vs 500k+ lines of Perl), so it's not a priority compared
to the Perl, and the Perl stuff is still in progress. JavaScript also has
strict, which can catch some common problems, like the global scope "this".

------
0942v8653
This looks very useful, and there are some things on there I didn't know you
had to do in bash. Here's a SublimeLinter plugin:
[http://github.com/SublimeLinter/SublimeLinter-
shellcheck](http://github.com/SublimeLinter/SublimeLinter-shellcheck)

------
zwischenzug
Available as a Docker ShutIt module if you don't want to install it:

docker run -t -i -v /path/to/code/code.sh:/code.sh imiell/sd_shellcheck
shellcheck /code.sh

------
Chmouel
There is this tools as well developed in OpenStack:
[https://github.com/openstack-dev/bashate](https://github.com/openstack-
dev/bashate)

------
nodesocket
Awesome, thanks for this.

------
anonfunction
Cool tool but I'm really confused by the name choice. Sure choosing names is
hard but by using a name of a common tool for an unrelated tool will just
cause problems for people looking for bash spellcheck tools.

~~~
koala_man
I'm the author! Since naming the tool, I've discovered that a significant
segment of the population (such as yourself) repeatedly misread the name as
"spellcheck".

The name is actually "shellcheck" (shell + check).

It's a fascinating effect because people seem to be very consistent in whether
they read it one way or the other. If linguists don't already have a name for
this sharp, binary classification, I propose "n-Gram staining".

~~~
uaygsfdbzf
Some ideas for the future:

Add support for the Firehose XML output format:

[https://github.com/fedora-static-
analysis/firehose](https://github.com/fedora-static-analysis/firehose)

Checks for features that are specific to one shell (bashisms etc) when used
with POSIX #!/bin/sh.

Checks for features that aren't implemented in the desired shell (for running
on busybox sh for example).

Check for the various issues listed here:

[http://mywiki.wooledge.org/BashPitfalls](http://mywiki.wooledge.org/BashPitfalls)

~~~
koala_man
Thanks!

ShellCheck already checks for bashism if the script is declared with
#!/bin/sh, and finds most of the ones that checkbashisms does along with a few
others. It's geared towards POSIX compliance though, and doesn't know which
non-POSIX feature are available in e.g. busybox sh.

There is also some limited support for warning about features not available
between non-POSIX shells, such as trying to use zsh =(temp files) in bash or
bash ;;& case continuations in zsh, but this isn't as much of a focus as POSIX
checks since it's not a common source of issues.

The Wooledge pitfall list was the original implementation checklist. About 38
out of the 46 are already covered in one form or another.

I haven't heard of Firehose before, but if you want to use it right now you
can run shellcheck with -f gcc, to get gcc style error messages that Firehose
can already parse.

