48

Are there any shell (specifically bash or ksh) checkers that test shell scripts for style, best practices, naming conventions, etc? (Something like Lint for C, or Perl::Critic for Perl.)

I know with ksh you can do syntax checking by running ksh -n script.ksh but I was hoping for something more than just sytax checking - something that parses/analyzes the actual code?

I'm probably out of luck, but I guess it doesn't hurt to ask.

John Conde
  • 217,595
  • 99
  • 455
  • 496
BrianH
  • 7,932
  • 10
  • 50
  • 71

3 Answers3

46

I found shellcheck: it tests for common errors in quoting and other things you overlook ("because it works").

mklement0
  • 382,024
  • 64
  • 607
  • 775
u0b34a0f6ae
  • 48,117
  • 14
  • 92
  • 101
  • 1
    It's too bad it depends on Haskell. It's nice, but haskell is a kinda huge dependency. – Ehtesh Choudhury Apr 14 '13 at 02:39
  • 2
    @Shurane - the dependency is necessary only for building, not for running the executable. – Deer Hunter Jun 19 '13 at 08:52
  • 2
    It appears that the only dependency is a browser. – msanford Jan 22 '14 at 20:52
  • I too wish that running the binary locally didn't require haskell to build, but I'm thankful for the web interface. – morgant Feb 19 '14 at 20:35
  • 1
    I just found shellcheck too, and it's a really useful and easy tool. – Simon Michael Jan 28 '15 at 15:59
  • I found shellcheck too, and it's a really useful and easy tool. By now it's in Debian testing and Ubuntu trusty-backports. If it's not packaged for your OS yet, Haskell probably is, so a simple `apt-get install cabal` or equivalent followed by `cabal install shellcheck` will probably install it. (Otherwise http://www.stackage.org/install is a good guide for quick Haskell setup.) – Simon Michael Jan 28 '15 at 16:07
  • 1
    Great tip; on OSX you can now also install the shellcheck.net CLI, `shellcheck`, via [Homebrew](http://brew.sh): `brew install shellcheck`. – mklement0 Jun 12 '15 at 02:19
35

The Debian and Ubuntu projects use a script checkbashisms, that looks for particular patterns that might indicate that someone is relying on /bin/sh being bash.

Beyond that, most shells have a -n option to parse and report errors. You could check your script against several different shells to make sure it uses only portable syntax:

for shell in zsh ksh bash dash sh
do
  echo "Testing ${shell}"
  ${shell} -n my_script.sh
done

edit to add: Since writing this answer, shellcheck has been written, as suggested in a later answer. This does a much more thorough job of linting shell scripts than the previous suggestions.

Community
  • 1
  • 1
Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • Cool - that script looks promising! And judging by my lack of finding anything else, and the lack of responses, I'd say that's probably the only thing out there that does this type of thing. Thanks very much! – BrianH Sep 10 '10 at 18:24
  • 1
    Is it me or this option is not in the man page of bash nor zsh ? – log0 May 24 '12 at 14:45
  • 1
    Why can't the bash interpreter of the 21st century give a more useful message like "the 'if' on line 23 has no matching 'fi' ..." instead of frustratingly useless nonsense like this? $ bash -n /tmp/baa.sh /tmp/baa.sh: line 56: syntax error: unexpected end of file $ zsh -n /tmp/baa.sh /tmp/baa.sh:56: parse error near `\n' – MarkHu Oct 23 '12 at 01:40
  • @BrianCampbell That's fantastic! I plan to fork a repo just for that snippet! – apennebaker Nov 20 '13 at 18:12
  • It's helpful that this script can perform a basic syntax check on scripts for multiple shells, but it really doesn't answer @BrianH's question regarding parsing/analyzing. – morgant Feb 19 '14 at 20:34
9

I wrote shlint to wrap checkbashims and the other basic linting options available to shells presented in Brian's answer.

It's installable via rubygems (gem install shlint) as sort of a gag, really, but you only need perl (for checkbashims) and a POSIX compliant shell to interpret the shlint command itself. Should work out of the box on OSX and Ubuntu.

Ross Duggan
  • 463
  • 3
  • 6