ShellCheck: shell script analysis

Shell scripting is notoriously full of pitfalls, unintuitive behavior and poor error messages. Here are some things you might have experienced:

  • find -exec fails on commands that are perfectly valid
  • 0==1 is apparently true
  • Comparisons are always false, and write files while failing
  • Variable values are available inside loops, but reset afterwards
  • Looping over filenames with spaces fails, and quoting doesn’t help

 

ShellCheck is my latest project. It will check shell scripts for all of the above, and also tries to give helpful tips and suggestions for otherwise working ones. You can paste your script and have it checked it online, or you can downloaded it and run it locally.

Other things it checks for includes reading from and redirecting to a file in the same pipeline, useless uses of cat, apparent variable use that won’t expand, too much or too little quoting in [[ ]], not quoting globs passed to find, and instead of just saying “syntax error near unexpected token `fi'”, it points to the relevant if statement and suggests that you might be missing a ‘then’.

It’s still in the early stages, but has now reached the point where it can be useful. The online version has a feedback button (in the top right of your annotated script), so feel free to try it out and submit suggestions!

14 thoughts on “ShellCheck: shell script analysis”

  1. Could you add checks for bashims and other non-portable junk?

    – warn on use of [[ ]] when [ ] would work
    – #!/bin/bash instead of #!/bin/sh
    etc

  2. @A name
    It already warns about some bashisms when using #!/bin/sh, and this could definitely be expanded and improved. Thanks!

    If the user wants to write a bash/zsh/ksh script instead of a sh script, though, I’d be inclined to let them as long as they declare it in the shebang.

  3. Thanks for this extremely useful tool. Would you consider adding a \Clear\ button that clears the \Paste shell script\ edit box, in order to be able to paste the next shell script?

  4. @A name
    As of today, ShellCheck does the majority of checks that ‘checkbashisms’ would have when #!/bin/sh is used.

  5. Hi Vidar,

    Congratulations for your great work!

    I’m trying to run ShellCheck locally in a Red Hat 6.4 but when I try to install cabal (to build ShellCheck) I got:

    > sudo yum install cabal-install

    –> Finished Dependency Resolution
    Error: Package: ghc-base-devel-4.3.1.0-46.el6.x86_64 (epel)
    Requires: libffi-devel

    And if I try to use a ShellCheck built previously in Ubuntu I got:

    > shellcheck file.sh

    shellcheck: error while loading shared libraries: libgmp.so.10: cannot open shared object file: No such file or directory

    Could you help with this?

  6. Yes:

    > sudo yum install libffi-devel


    No package libffi-devel available.
    Error: Nothing to do

  7. @Marcelo
    Well, I don’t know. If you can build on Ubuntu, you can try
    make clean; ghc --make shellcheck -optl-static -optl-pthread to compile a statically linked version that doesn’t depend on external libraries like libgmp.

  8. Great! It seems that it worked pretty well! If I find any issue I will let you know. Consider to put this in the README.md file.

    Thanks a lot. Congratulations again!

  9. Hi Vidar!

    Thanks for this thing, it’s pretty useful!

    One question, is it possible to extend analysis rule somehow? I am going to integrate static code analysis into our development process, but will be useful to have some addition checks. In my gut feeling, I have to extend Analytics.hs. Do I right?

    Also, could you please recommend any books / articles about implementation of tools like yours?

    Thanks in advance!

    Thanks,
    Alexander

  10. @Alexander
    You can either modify Analytics.hs (or sometimes Parser.hs), or create a new Haskell project that uses ShellCheck to parse and then examine the AST however you want.

    Unfortunately I don’t have any recommendations for general reading material of parsing or static analysis

Leave a Reply