[HN Gopher] ShellCheck: A static analysis tool for shell scripts
       ___________________________________________________________________
        
       ShellCheck: A static analysis tool for shell scripts
        
       Author : ducktective
       Score  : 209 points
       Date   : 2021-03-18 16:49 UTC (6 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | pvinis wrote:
       | I just tried to use it this morning. I had an if with [[ ]] and
       | one with [ ] so I hoped for advice. No errors or warnings. Then I
       | didn't bother using it anymore. Furthermore, I switched the
       | script to use deno!
        
         | miduil wrote:
         | shellcheck won't force you to prefer one of the two variants,
         | hence the difference is relatively subtle to a degree that even
         | documentation is not superhelpful either:
         | https://www.oilshell.org/blog/2016/10/12.html
         | 
         | shellcheck will show you many more mistakes that are much more
         | painful your example and also very common.
         | 
         | Deno is definitively an interesting language, but Shell
         | scripting is the gateway to bootstrap so many of your beloved
         | programming languages. If your environment allows it always
         | prefer a proper programming language over shell scripting.
         | Shell scripts are meant for Unix operating system operations,
         | setting few variables, combining certain data-sources, doing
         | filesystem operations, ...
        
       | __bjoernd wrote:
       | Great tool that everyone should be using for shell scripts!
       | 
       | Then again, I've learnt more than once that you start with "I'm
       | just capturing a few commands in a script" and the next thing you
       | see is a mess of special characters, crude syntax and nasty error
       | handling. Don't be like me...
        
         | cylon13 wrote:
         | I find it helps if you have a hard rewrite rule. I really love
         | the convenience of shell scripts for small scripts, but as soon
         | as I have one that crosses 100 lines I rewrite it in python.
         | The python version is a bit less convenient for spawning
         | processes and piping them together, but it's so much more
         | maintainable that you can scale it up to quite a bit larger
         | without as much worry. 100 lines is a nice size where it
         | doesn't take very long to rewrite, so even though I figure I
         | could get away with a longer shell script without it getting
         | too bad, I'm definitely not going to want to rewrite it once it
         | gets big enough to be a problem.
        
           | kawsper wrote:
           | I am you, except my go-to is Ruby.
        
           | atleta wrote:
           | Invoke [1] can make it a bit more convenient.
           | 
           | [1] https://www.pyinvoke.org/
        
       | ghostwriter wrote:
       | A great highlight of how great Haskell parser combinators can be
       | in the domain of linters.
        
       | knoebber wrote:
       | ShellCheck made me confident enough to write more complex bash
       | scripts. Highly recommend! Works great with emacs + flycheck.
        
         | ollran wrote:
         | It is also a quite nice tool for checking the POSIX
         | compatibility of shell scripts. I find it very useful when
         | working on Solaris or some other UNIX that does not use Bash by
         | default.
        
           | lipanski wrote:
           | Same here, I basically learned how to write POSIX-compliant
           | Shell with the help of ShellCheck. Shell is not a difficult
           | language to learn but it definitely has its oddities and the
           | different flavours (Bash etc.) only add to the confusion.
           | 
           | What people don't always expect is the immense portability
           | that POSIX-compliant Shell offers you. This thing runs on
           | pretty much everything.
        
       | acdha wrote:
       | This is one of my favorite tips for almost effortlessly improving
       | devops productivity (along with using https://github.com/mvdan/sh
       | for auto-formatting) -- by now shellcheck has good editor support
       | in e.g. VSCode and I have a standard pre-commit.com hook for all
       | of my projects. I've seen so many long iterations where people
       | flail at a complex shell script for something like a cron job
       | which was immediately flagged by shellcheck. I generally
       | recommend rewriting in Python but this is a good less invasive
       | step.
       | 
       | One thing which might be worth considering is adding this to your
       | personal ~/.shellcheckrc to make it more pedantic:
       | 
       | enable=all
        
       | tyingq wrote:
       | I haven't used it, but I have seen something similar called
       | shellharden. It pitches it's advantage as being able to auto
       | apply the changes.
       | 
       | https://github.com/anordal/shellharden
        
       | exdsq wrote:
       | Alongside ShellCheck, I also use shUnit2 as my unit testing
       | framework. These two combined have let me write some pretty long
       | (~1k loc) bash programs that work. Yes, you should test your
       | bash.
       | 
       | https://github.com/kward/shunit2
        
         | ducktective wrote:
         | There are quite a few unit-testing frameworks for bash. I
         | wonder, have you reviewed and compared them and came to
         | `shunit2`?
        
           | exdsq wrote:
           | I tried one or two but decided on shUnit2 because it seemed
           | to be the most friendly and familiar. If you have suggestions
           | of alternatives I'd love to hear them!
        
       | DiabloD3 wrote:
       | I use ShellCheck, its a great linting tool. All the vim linting
       | frontends support it.
        
         | ducktective wrote:
         | yeah, for integration with coc-nvim, take a look at this github
         | comment:
         | https://github.com/meatwallace/dotfiles/issues/129#issuecomm...
         | 
         | There is also a LSP at : https://github.com/bash-lsp/bash-
         | language-server
        
       | thitcanh wrote:
       | I love linters and formatters. Often languages carry baggage and
       | other "bad parts" that linters help you avoid.
       | 
       | For someone who's not used to them they might feel annoying (e.g.
       | why should I wrap every $() in quotes?! Ugh) but once you accept
       | them your code will be a million times better and safer.
        
         | omn1 wrote:
         | Same. Few years ago I started a little list of linters. Just
         | kept adding tools and the list is huge now thanks to lots of
         | contributors. https://github.com/analysis-tools-dev/static-
         | analysis Still love adding new linters there when I cross their
         | path. :)
        
       | devy wrote:
       | This has been brought up ten times since 2014 when it first
       | appears on HN :)
       | 
       | Click on the site link[1] in parenthesis to the right of the
       | title, you will see.
       | 
       | [1]: https://news.ycombinator.com/from?site=github.com/koalaman
        
         | abathur wrote:
         | And 23 more for
         | https://news.ycombinator.com/from?site=shellcheck.net :)
        
         | llarsson wrote:
         | It is actually good enough to be here that often. More often,
         | even.
         | 
         | It's like in this xkcd. It's always new to somebody.
         | 
         | https://xkcd.com/1053/
        
       | dang wrote:
       | If curious, the interesting past threads seem to be:
       | 
       |  _Lessons learned from writing ShellCheck_ -
       | https://news.ycombinator.com/item?id=22279585 - Feb 2020 (46
       | comments)
       | 
       |  _Shellcheck: a static analysis tool for shell scripts_ -
       | https://news.ycombinator.com/item?id=9001931 - Feb 2015 (46
       | comments)
       | 
       |  _ShellCheck: a static analysis and linting tool for sh /bash
       | scripts_ - https://news.ycombinator.com/item?id=8777705 - Dec
       | 2014 (20 comments)
       | 
       |  _ShellCheck - Online shell script analyzer_ -
       | https://news.ycombinator.com/item?id=8182745 - Aug 2014 (14
       | comments)
        
       | hivacruz wrote:
       | To use in combination with shfmt : https://github.com/mvdan/sh
        
       | ufo wrote:
       | One of my favorite things about Shellcheck is that the error
       | messages come with a link to a wiki page about the problem. Does
       | anyone know other programs that have a similar approach to error
       | messages?
       | 
       | https://github.com/koalaman/shellcheck/wiki/Checks
        
         | monoideism wrote:
         | Many of the JS linters do (eslint, etc).
        
         | varbhat wrote:
         | Rust Compiler Error Index
         | 
         | https://doc.rust-lang.org/error-index.html
        
           | mitmaro wrote:
           | Related, Clippy, a linter for Rust also does the same and
           | links to https://rust-lang.github.io/rust-
           | clippy/master/index.html .
        
         | DiabloD3 wrote:
         | Yeah, C# compilers do. Easily Googleable error code to further
         | explain it.
        
           | oblio wrote:
           | I think it's a Microsoft thing. A ton of their stuff has
           | unique error codes just for this purpose.
        
             | _pmf_ wrote:
             | All heavily internationalized software should have error
             | codes.
        
             | trinix912 wrote:
             | Remember back when OS/2 had a special error code for every
             | error message?
        
               | SSLy wrote:
               | Codes like that are a part of IBM culture that spilled
               | out to other companies.
        
             | llarsson wrote:
             | Sure beats the General Protection Fault we were so
             | accustomed to back in the day. :)
        
         | KronisLV wrote:
         | I recall working with AngularJS, which output error messages
         | that had links, which opened the documentation with bits from
         | your stack trace filled in.
         | 
         | It was a while ago and seemed a bit gimmicky, but i really
         | enjoyed the ability to see what could be done about an error by
         | opening a web page (without having to manually dig through
         | StackOverflow or other sites).
         | 
         | Now, if we'd get a development framework that'd couple
         | documentation like that, with user generated comments (like PHP
         | has, for example see the bottom of
         | https://www.php.net/manual/en/function.strcmp.php ), then i
         | think the developer experience would improve a bunch!
         | 
         | Who knows, maybe even allow users to contribute possible fixes
         | and allow those as autocomplete solutions and you've just
         | improved on what tools like Codota do a whole bunch!
        
         | tyingq wrote:
         | find-sec-bugs does that. It's used by, for example, SonarQube.
         | 
         | See https://github.com/find-sec-bugs/find-sec-
         | bugs/blob/master/f...
        
         | thepratt wrote:
         | Hadolint is another. It's built atop shellcheck.
         | 
         | https://github.com/hadolint/hadolint
        
         | rakingleaves wrote:
         | Error Prone does this: https://errorprone.info/bugpatterns
        
         | imoverclocked wrote:
         | Errorprone (java compiler plug-in) has this as does NullAway
         | (an errorprone plug-in)
         | 
         | I agree that it's really handy, especially when implementing
         | the check in a CI pipeline with lots of developers.
        
       | parhamn wrote:
       | Not near a terminal right now but it would be fun to run my shell
       | history through this to see if I learn anything. Anyone try it?
        
         | jkingsman wrote:
         | Unless you're composing very rich commands, likely not much
         | will show up. It exceeds at finding things like interpolation
         | gotchas, bad loop control, etc. Much more structural than just
         | one off commands (though would likely bug about a bunch of
         | useless `cat`s when you can use redirect operators instead
         | (i.e. `cat foo.txt | grep` is an antipattern according to
         | shellcheck)
        
       ___________________________________________________________________
       (page generated 2021-03-18 23:00 UTC)