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!
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
@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.
Very Cool & useful tool .. Thanks
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?
@mike
Done!
@Vidar
Thanks!
@A name
As of today, ShellCheck does the majority of checks that ‘checkbashisms’ would have when #!/bin/sh is used.
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?
@Marcelo
Did you try installing the additional dependencies yum complains about?
Yes:
> sudo yum install libffi-devel
…
No package libffi-devel available.
Error: Nothing to do
@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.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!
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
@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