back

by jasonpeacock·7y ago·view on hn ↗
Yes! So much yes. Many developers write crappy Bash scripts because they don't see it as a real language, but it's an interpreted language just like Ruby, Python, Perl, etc.

If you're going to design modular libraries and scripts with best practices, unit tests, etc, for those languages, then you should be doing the same with Bash.

If you're writing production scripts using Bash, you should be following software best practices - don't give me any "it's just Bash" excuses.

Mocking In addition to bats-mock (part of the bats library in the article), there is another mocking approach: https://pbrisbin.com/posts/mocking_bash/ They both have their uses.

Documentation NaturalDocs ( https://www.naturaldocs.org/ ) can happily parse & extract doc comments from your bash scripts & libraries: https://www.naturaldocs.org/ Just define your own language:

https://www.naturaldocs.org/reference/languages.txt/#adding_...

  Format: 1.4
  
  Language: bash
  Shebang Strings: bash
  Extensions: bash sh
  Ignore Extensions: bats
  Line Comments: #
Linting Use shellcheck, it's amazing: https://www.shellcheck.net/ If you use Vim, w0rp/ale knows how to integrate with it for real-time feedback: https://github.com/w0rp/ale/tree/master/ale_linters/sh

Argument Parsing Use Docopt ( http://docopt.org/ ) to get modern arg-parsing in your Bash scripts. Don't waste your time trying to roll your own or use the built-in anemic arg-parsing. Shells implementation: https://github.com/docopt/docopts

Use Bash built-ins Stop invoking external processes for features already available in Bash: https://github.com/dylanaraps/pure-bash-bible

More good resources:

* http://www.tldp.org/LDP/abs/html/

* https://www.gnu.org/software/bash/manual/bashref.html

* http://mywiki.wooledge.org/BashGuide

BUT why are you using Bash? Go use a modern language and don't suffer the idiosyncrasies of Bash where you have to re-invent many common libraries already available like JSON parsers, etc.

My favorite Bash replacement is Python + Plumbum: https://plumbum.readthedocs.io/en/latest/ All the convenience of Bash when invoking commands (no more subprocess()!) with the joy of Python.

2 comments
> Linting Use shellcheck

Shellcheck has saved me countless times, but I noticed it's hard to get people to adopt it into their workflow.

I've introduced probably a dozen people to shellcheck and warn them ahead of time that their scripts are broken. They try it, see a flood of errors and warnings, close the window, and never use it again.

The logic surrounding their undefined variables and improper conditions happen to work as hoped, by luck, combined with their strict adherence to "it's best practice to not use spaces" both keep their scripts crawling along "just fine".

I just went to install it with macports, it says:

"The following dependencies will be installed: autoconf automake bzip2 clang-3.3 clang-4.0 clang_select cmake curl curl-ca-bundle db48 expat gcc6 gdbm ghc ghc-bootstrap glib2 gmake gmp help2man hs-json hs-mtl hs-parsec hs-primitive hs-quickcheck-devel hs-random hs-regex-base hs-regex-tdfa hs-syb hs-text hs-tf-random icu isl ld64 ld64-97 legacy-support libarchive libcxx libedit libffi libgcc libgcc6 libgcc7 libidn2 libmpc libomp libpsl libtool libunistring libuv libxml2 libxslt llvm-3.3 llvm-3.5 llvm-4.0 llvm_select lz4 lzo2 m4 mpfr openssl p5.28-locale-gettext pcre perl5 perl5.26 perl5.28 pkgconfig python27 python2_select python_select readline sqlite3 texinfo xar xattr zlib zstd Continue [Y/n]:" ..uh maybe not right now.

It looks like the MacPorts version of shellcheck is substantially out-of-date[1].

`brew info shellcheck` shows just three (build-time) dependencies: cabal-install, ghc, and pandoc.

[1]: https://github.com/macports/macports-ports/commits/master/de...

Yes, it hasn't been updated because dependencies have to be updated first. See recent discussion on updating ghc: https://trac.macports.org/ticket/48899#comment:43.
Oh thanks! That's a fascinating discussion.
Yeah, probably is, I only use macports as my computer is substantially out of date (2006)! But even my 'port info shellcheck' (0.3.8) only says:

Build Dependencies: apple-gcc42

Library Dependencies: ghc, hs-json, hs-mtl, hs-parsec, hs-quickcheck-devel, hs-regex-tdfa

I like how there's GCC, GCC6, GCC7, LLVM-3.3, LLVM-3.5, and LLVM-4.0...
> If you're going to design modular libraries and scripts with best practices, unit tests, etc, for those languages, then you should be doing the same with Bash.

Or: not use Bash at all.

Which is exactly my closing argument :)
Well now I just feel dumb.