[HN Gopher] Ask HN: Let's build Checkstyle for Bash?
       ___________________________________________________________________
        
       Ask HN: Let's build Checkstyle for Bash?
        
       After working with Bash and Shellcheck for a few months, I noticed
       I could improve my code quality by making it compliant with the
       Shell Style Guide by Google [0]. While working on that, I thought
       some aspects of this Shell style guide can be verified
       automatically, granted some assumptions/opinions are formed. So I
       looked around for linting tools and autoformatters for Bash:
       Shellcheck: https://github.com/koalaman/shellcheck  From
       Asynchronous Lint Engine (ALE): https://github.com/dense-
       analysis/ale/blob/master/supported-...  - bashate:
       https://github.com/openstack/bashate  - cspell:
       https://github.com/streetsidesoftware/cspell/tree/main/packa...  -
       Bash Language Server: https://github.com/bash-lsp/bash-language-
       server  - shell -n flag:
       https://www.gnu.org/software/bash/manual/bash.html#index-set  -
       sh(shfmt): https://github.com/mvdan/sh  - shdoc:
       https://github.com/reconquest/shdoc  From this stack post [1]:  -
       checkbashisms: http://man.he.net/man1/checkbashisms  - shlint:
       https://github.com/duggan/shlint (archived)  Prettier:
       https://marketplace.visualstudio.com/items?itemName=esbenp.p...
       Within all these linters and auto-formatters I did not find checks
       that enforce, for example, the Function Comments of the Shell Style
       Guide by Google:  All function comments should describe the
       intended API behaviour using:                   Description of the
       function.         Globals: List of global variables used and
       modified.         Arguments: Arguments taken.         Outputs:
       Output to STDOUT or STDERR.         Returns: Returned values other
       than the default exit status of the last command run.       Hence,
       I thought we could make a Bash linting tool that verifies
       compliance with the Shell Style Guide by Google. To do so, a brief
       start was made here [2]. It identifies/lists elements in that style
       guide that may be verified automatically. Since Bash has been
       around longer than me, I think there may be some people better
       suited for the development of this enhanced linter. Hence, I
       thought it might be wise, for impact and usability, to share this
       idea here.  What do you say, HN?  [0]:
       https://google.github.io/styleguide/shellguide.html  [1]:
       https://stackoverflow.com/questions/3668665/is-there-a-stati...
       [2]: https://github.com/TruCol/checkstyle-for-bash
        
       Author : a-t-0
       Score  : 47 points
       Date   : 2022-02-20 12:29 UTC (10 hours ago)
        
       | Etheryte wrote:
       | Out of pure curiosity, in what context do you write sufficient
       | amounts of Bash scripts that style checking is a worry that needs
       | your attention? While I also write small one-offs or bootstrap
       | scripts here and there, in most cases it's my experience that
       | developers opt for other languages for anything beyond small
       | snippets.
        
         | zinekeller wrote:
         | Largely same sentiment. Pure POSIX shell scripts for embedded
         | systems, sure, but I'm not sure if there is a niche that
         | requires Bash scripting. Not discouraging these efforts of
         | course but I'm not sure that it'll be worth it.
        
           | amelius wrote:
           | The niche is installer scripts. Because there is one
           | certainty: Bash is available everywhere.
        
             | fjorde wrote:
             | zinekeller's point notwithstanding, i agree that "installer
             | scripts" is really the last necessary domain of the bash
             | script. If you need a (semi)portable script to get `python`
             | to run your python script, you can't use python, obviously.
             | 
             | Things like docker images and nix builds are sold as huge
             | improvements on this chicken-egg problem, at least from a
             | "keep it all in one language" perspective, but only if you
             | consider a docker script (mostly bash) or a nix config
             | truly not the same thing as a shell script that more or
             | less initiates the same environment.
             | 
             | docker/nix abstraction layers have advantages but aren't
             | always as portable as a shell script. If you need a docker
             | engine, I think you'll still need a bash script to install
             | that...
             | 
             | Nix is possibly even more "single command", often just a
             | curl if i'm not mistaken, but still requires config and
             | shipping a build somewhere, and you still need to run the
             | `curl` command in a shell somehow. i don't see how "just
             | use python" will ever fix the init chicken-egg problem.
        
             | zinekeller wrote:
             | > Bash is available everywhere
             | 
             | POSIX mistake number 1: Bash _isn 't_ available everywhere,
             | _even when restricted to Linux_. Even Debian avoids bash
             | for a good reason (Bash _is_ slower than most POSIX shell
             | implementations), although it 's installed by default for
             | convenience.
        
               | drran wrote:
               | > Even [on] Debian ... it's installed by default for
               | convenience.
               | 
               | :-/
        
         | nickjj wrote:
         | Every web application I work with has this idea of a "run"
         | script[0], basically a self isolated shell script to help
         | automate running certain commands. Sort of like a Makefile
         | except with the full power of your shell.
         | 
         | For example: https://github.com/nickjj/docker-flask-
         | example/blob/main/run
         | 
         | In a bigger project this file tends to grow quite large, even
         | when you have the power of a programming language available to
         | you there's plenty of tasks where it makes sense to keep it as
         | a shell script. Now imagine you work on a team where other
         | folks want to contribute new functionality, it's important to
         | have automated tools to help stick with a consistent style,
         | just like you would want to use Black with Python.
         | 
         | The run script for my infrastructure repo at one place I work
         | for is almost 1,500 lines of shell scripting that's broken up
         | into many small functions. It's not a big jumbled mess either,
         | it's very organized and optimized to make running long commands
         | faster and less error prone (even if they happen to be called
         | in CI). These functions are mostly calling out to Terraform and
         | other tools too, it's not 1,500 lines because of long winded
         | cloud CLI tool API calls or anything like that.
         | 
         | [0]: https://nickjanetakis.com/blog/replacing-make-with-a-
         | shell-s...
        
         | brimstedt wrote:
         | What do you use the; if you want:
         | 
         | - Self contained in one file
         | 
         | - Easily edited with vi/nano (i.e. through a console ssh
         | session)
         | 
         | - Readily available on most Linux base installations
         | 
         | - No crazy runtime installation requirements
         | 
         | Edit: formatting)
        
           | neoromantique wrote:
           | python.
        
             | drran wrote:
             | perl
        
               | neoromantique wrote:
               | Not my cuppa, but I'd take it over bash any day
        
             | ducktective wrote:
             | Which python? 2.7 that is symlinked to `python` on the
             | distro? 3.5 that is installed by default? or perhaps you
             | meant 3.9 but what about that cool library that you're
             | gonna use which is only available for 3.9.2 and not 3.9.1
             | due to a bug?
             | 
             | How are you gonna handle installing that beautifulsoup
             | dependency in a way that does not bork the OS python deps?
             | 
             | Are you gonna use `python -m venv` or `poetry` or `pipenv`?
        
           | kodah wrote:
           | Some context to my statements: I'm a SWE that works on
           | infrastructure services and tooling, primarily on Linux but
           | also Unixes.
           | 
           | It depends on what I'm doing but usually Go if an application
           | requires any longevity at all.
           | 
           | I use Python or Java for things that require more dynamic
           | typing. The main usecase here is big data or to prototype
           | applications.
           | 
           | Bash I usually reserve for _very_ small tasks. When I
           | bootstrap services in containers, you 'll usually find some
           | Bash. A whole CLI written in Bash? I would not approve that
           | PR. Bash lacks variable scoping for the most part, the ways
           | in which you can implement it are hacky and non-obvious.
           | Bash's syntax and the way it behaves varies by system, even
           | installer scripts have to account for this. As I'm typing
           | this, I realize the Bash code I write generally follows the
           | same testing and constraints as the Makefiles I write.
           | 
           | I don't think I really understand the requirement for "a
           | single document". This departs from programming practices
           | I've built up over the years. When I come across large multi-
           | thousand LOC documents (in any language, much less Bash) I'm
           | usually concerned.
        
           | hnlmorg wrote:
           | If it is for myself: murex (my own DevOps focused shell:
           | https://murex.rocks)
           | 
           | If it is for work: either Bash or whatever that companies
           | preferred software development language (over the last ~20
           | years that's included: Pascal, Visual Basic, PL/SQL, Perl,
           | PHP, Python, Typescript and others I've likely forgotten.
           | Different companies will have different preferences)
           | 
           | If performance matters then these days Go is my "goto"
           | language because it's a good compromise in terms of developer
           | productivity and application performance. But I've used Java,
           | C and C++ too. Depending on the particular problem I'm trying
           | to solve.
           | 
           | ...and if you ask me again in 5 years then the answer will be
           | completely different again.
           | 
           | The sort answer is: there's no such thing as a single answer.
           | Everyone will have their own preferences and business
           | requirements.
        
         | cmckn wrote:
         | I think linters are just as helpful for 10 lines as they are
         | for 1000. I (try to) use style checks and formatters for
         | anything and everything I version-control, especially when
         | there's more than one person working on it concurrently.
        
       | ancientsofmumu wrote:
       | Google's styleguide has incorrect bash being used, they are using
       | string comparison operators for numeric comparisons (see the
       | various `$? != 0` and $PIPESTATUS).                   [[ -1 -eq
       | 0-1 ]] && echo true || echo false         [[ -1 == 0-1 ]] && echo
       | true || echo false
       | 
       | https://www.gnu.org/software/bash/manual/html_node/Bash-Cond...
        
         | esprehn wrote:
         | The style guide always uses (( so the operators are numerical
         | comparison.
         | 
         | See also where it says: > For preference, don't use [[ ... ]]
         | at all for numeric comparisons, use (( ... )) instead.
        
       | eternityforest wrote:
       | I think we should really be working to deprecate large bash
       | scripts. If you write enough to care about code quality you might
       | want to just use Python.
       | 
       | I'd say look at things like Oil(Is that project ever going to be
       | the next big thing like it claims?).... but writing large scripts
       | in ANY shell doesn't seem like the best plan.
       | 
       | What about an Ansible linter? Do those exist? I'm starting to
       | suspect Ansible might be a better choice for a lot of what people
       | do with bash, even if you are running om a desktop.
        
         | monkeybutton wrote:
         | Seconded. I use Python daily and bash monthly at best. After
         | the Nth time looking up how to do specific kind of conditional
         | check in bash, I gave up started writing all the extra scripts
         | and tooling I need using Python instead.
        
         | cjvirtucio wrote:
         | Ansible has a linter. We do use it on our playbooks (locally
         | and in CI). There's also a framework for testing and linting
         | ansible plugins (ansible-test IIRC), though that's been a
         | little painful for us to setup.
         | 
         | That said, we do have a lot of helper scripts that we use in
         | our day-to-day (local development). They're not "large bash
         | scripts", but they're small enough that we don't really need a
         | proper programming language. Some degree of code quality with
         | style guides and shellcheck does help.
        
         | caslon wrote:
         | Shell scripts are nicer than Python, though. There was a brief
         | moment in time where Python nearly rivaled shell scripts in
         | convenience and straightforwardness, but November of 2008 was
         | many years ago, now.
         | 
         | We should probably deprecate Bash, though. It doesn't offer
         | enough over the standard for it to be worth it.
        
           | rascul wrote:
           | > We should probably deprecate Bash, though. It doesn't offer
           | enough over the standard for it to be worth it.
           | 
           | Arrays make a world of a difference. Deprecate sh, keep bash.
        
             | caslon wrote:
             | That's a terrible idea. A shell scripting language doesn't
             | _need_ to do everything in the world. It just needs to tape
             | together tools that _can_ do everything.
             | 
             | POSIX sh can pass arrays around just fine, and that's all
             | it needs to do. Feature creep is the worst possible thing
             | you could do to a shell scripting language.
        
               | iforgotpassword wrote:
               | No it can't. You have the argument array which is a
               | horrible workaround. If you need to write scripts that
               | interact with other tools a lot, bash is the language of
               | choice. Starting and handling other processes is a messy
               | thing in any other language.
        
               | caslon wrote:
               | It's not a terrible workaround; it's a beautiful
               | demonstration of how flexible the standard shell is.
        
               | rascul wrote:
               | It's a bit of an inefficient hack compared to a language
               | feature.
        
               | 1500100900 wrote:
               | Which POSIX sh do you have in mind and how does one pass
               | arrays around in it?
        
               | caslon wrote:
               | POSIX sh. Pass it as a string, use standard programs to
               | turn it into what you want. Voila. Not that hard. Just
               | like you do everything else in UNIX.
        
               | 1500100900 wrote:
               | If you mean a standard, it will be too abstract to be
               | considered as something that can run anything. Sometimes
               | it has to be too vague in order to not make existing
               | Bourne-style shells non-compliant. This isn't, for
               | example, a standard for the C programming language where
               | you can throw some things into the UB bag or the ID bag.
               | POSIX sh is more what you'd call "guidelines" than actual
               | standard.
               | 
               | Even if it were an implementation, how would you write a
               | "POSIX sh" equivalent of these lines taken from a bash
               | script? (My point isn't that it's impossible.)
               | 
               | mkdir -p /tmp/nodes/{a,b,c,d,e} ; NODES=(
               | /tmp/nodes/{a,b,c,d,e} ) ; echo ${NODES[$((`date +%-j` %
               | ${#NODES[@]}))]}
        
               | throwaway984393 wrote:
               | But POSIX sh doesn't have array support?
               | 
               | 99% of my use case for Bash over POSIX sh is arrays,
               | associative arrays, BASH_SOURCE, and PIPELINE (or
               | whatever that array is that has positional pipe return
               | status)
        
             | iforgotpassword wrote:
             | This. The problem most people have with bash scripts is
             | that they are mostly writing sh scripts and occasionally
             | throw in [[ ]] but still use 99% of the ugly workarounds
             | and tricks you had to use in sh to get anywhere.
        
         | axegon_ wrote:
         | > I think we should really be working to deprecate large bash
         | scripts.
         | 
         | I second this: I myself have a problem here, which, I guess is
         | somewhat related: I try to keep everything universal and each
         | time I try to generalize what I'm trying to achieve through
         | some sort of abstraction. As a consequence I keep adding
         | functions and aliases to my (zsh/bash)rc to the point where
         | they become absolutely unmanageable. At this very moment zshrc
         | is 8000+ lines long. Sure, I have a cronjob which backs it up
         | occasionally but it's more of a maintenance/readability hell.
        
           | necheffa wrote:
           | Have you considered that your run config is probably not the
           | place for this sort of thing? You could instead have focused
           | libraries in smaller files located at /usr/local/lib/ or
           | wherever tickles your fancy. Then source them as needed from
           | scripts.
        
             | axegon_ wrote:
             | I do that too but usually ends up being harder to keep
             | track of them and backup, even if I keep them in a separate
             | directory and added it to $PATH.
        
         | cushychicken wrote:
         | Where do you draw the line as "large"?
         | 
         | I just threw out a few hundred lines of Python in exchange for
         | ten lines of bash script + cron job to automate nightly app
         | updates. Way easier to get working, way less painful to debug.
         | 
         | I grant, however, that it's not particularly large. What is?
        
           | snidane wrote:
           | What Python is to Java, Bash is to Python.
           | 
           | Many simple file and data munging tasks can be done on cli
           | 100x faster with 10x less code than Python, using rudimentary
           | bash-fu.
           | 
           | I already see a wave of Python undoing in the data world.
           | Python becoming the cobol of this field.
        
             | cushychicken wrote:
             | I just learned about rev; rev plus cut could have saved me
             | _years_ of writing one off Python scripts to cut out the
             | exact variable I need, haha
             | 
             |  _rudimentary bash-fu_
             | 
             | I wish there were some guides on how to get past
             | rudimentary bash-fu. My bash text munging is still pretty
             | rudimentary. I'd love to get to journeyman text smash
             | status.
        
               | snidane wrote:
               | You might want to check out 'hck' to replace 'cut'.
               | 
               | https://github.com/sstadick/hck
        
               | cushychicken wrote:
               | I may give it a try - I have a bias to stuff that comes
               | preinstalled, though, as I know I'll always have the
               | chance to use it on a stock linux box.
        
           | Hizonner wrote:
           | So your 10 lines of bash use a bunch of other programs to do
           | almost all the work, right?
           | 
           | So what you need is a good language that lets you concisely
           | express ways of calling out to other programs. Not
           | necessarily a language that's backward-compatible with
           | whatever seemed like a good idea for a CLI in 1979.
        
             | cushychicken wrote:
             | Not even a bunch. It's calling a scraper written in Python,
             | date to add some timestamps, git to add new db entries and
             | push to version control, and touch to reload the webapp.
             | 
             | All that in... (goes off to wc -l the script) ...twenty
             | lines of bash, a third of which are comments.
             | 
             | > _language that lets you concisely express ways of calling
             | out to other programs_
             | 
             | Seems like bash meets those requirements to me, dawg.
             | /shrug
        
               | Hizonner wrote:
               | ... but you cut off the word "good"... :-)
        
               | cushychicken wrote:
               | "Good enough" is good in my book, and bash is good enough
               | for me.
               | 
               | Still wish someone would give me an idea of what "large"
               | means in bash scripts.
        
           | BiteCode_dev wrote:
           | When you start to need error handling.
        
             | cushychicken wrote:
             | ...unix return codes?
             | 
             | Sorry even I can't say that with a straight face XD
        
       | bashhacker wrote:
       | Take a look at shfmt and shdoc. One is an auto formatter, the
       | other does autodocs. I wouldn't invent yet another docstring
       | format. It's already been done. Just check compliance with an
       | existing format.
        
         | drran wrote:
         | I just did it. I use Markdown for bash-modules documentation.
         | :-/
         | 
         | A procedure in bash can have way more complex interface than
         | simple function call. See http://vlisivka.github.io/bash-
         | modules/arguments.html for example.
        
         | a-t-0 wrote:
         | @bashhacker, thank you for the suggestion! I included shdoc in
         | the list, and added the synonym shfmt to the sh formater (which
         | includes shfmt).
         | 
         | I agree with not making another docstring format. Accordingly,
         | I updated the readme to explicitly also allow the linter to
         | support the docstring format as provided by another style; that
         | of shdoc.
         | 
         | In essence, the user should be able to configure the linter to
         | adhere to Google Shell Style Guide or the one used by shdoc (or
         | another, or some non-conflicting combination of options). To
         | start somewhere, I propose Google Shell Style guide.
        
       | derefr wrote:
       | I've always been confused that in ${current_year} people are
       | still directly writing huge + complex shell scripts.
       | 
       | Compare/contrast Javascript, another language we're "stuck with":
       | while you _can_ still directly write it, many people don 't,
       | instead using transpilers to _target_ Javascript as an  "object
       | code" from some other, stricter language (e.g. TypeScript,
       | ClojureScript, arbitrary native languages via Emscripten / WASM
       | compiler targets, etc.) Via these languages/compilers, everybody
       | who wants compile-time strictness can have it. And you can even
       | get _runtime_ strictness that Javascript itself doesn 't have, as
       | the checked semantics of these languages will often be "lowered"
       | into the resulting Javascript by generating explicit assertions
       | (usually this is on by default, unless you ask for an optimized
       | build.) But the output is still just "Javascript", that any
       | browser can run.
       | 
       | Why hasn't a similar thing happened for POSIX-standard Bourne
       | shell? Why are we seemingly "satisfied" with writing +
       | maintaining 5000-line install.sh scripts in our codebases, with a
       | bunch of extra mental overhead / tooling required to keep the
       | code sane and clean; when we could just be writing in a sane and
       | clean language to begin with?
       | 
       | Is it just that nobody's bothered to create such a
       | language/compiler? Do I need to be the one to step up, here?
        
         | noahtallen wrote:
         | I don't think many are happy writing that much bash. I
         | certainly wouldn't be! I think this problem is completely
         | solved by other languages though.
         | 
         | Bash is popular because it's available (nearly) everywhere, is
         | very portable, and has a massive "standard library."
         | (Technically, not a standard library, but you can basically
         | guarantee that things like sed, curl, rsync etc. will be
         | available or easy to get anywhere.) And its constructs are very
         | well fitted to smaller scripts and automations.
         | 
         | You loose those benefits with a compilation step. Nearly all
         | the scripts I interact with are just smaller automations put
         | into a "bin" folder in the repo. These scripts are used for the
         | build steps of other programs. So what would you write for
         | automations related to building a compiled bash project?
         | Probably bash lol
         | 
         | If you're writing thousands of lines, you can just use any
         | other language, right? Pretty much any other scripting language
         | can execute commands in bash anyways. To my knowledge, stepping
         | into a different language once you need more refined flow
         | control and data structures is pretty normal. Afaik many
         | languages can either produce output which can be run directly
         | on the CLI (rust, C++, C), and others can be executed if you
         | have the language runtime installed (JS via node, python, etc.)
        
           | derefr wrote:
           | > Nearly all the scripts I interact with are just smaller
           | automations put into a "bin" folder in the repo.
           | 
           | What you're talking about are scripts you (or developers you
           | work closely with) write to then use yourselves, in
           | development workflows. These tend to be small and simple, and
           | also places where the pain-points of shell-scripting (e.g.
           | spaces screwing up path parsing) don't tend to come up,
           | because developers have enough sense to not make their
           | development environment actively hostile in these ways.
           | 
           | But this is not the only, or even the main, use-case of
           | writing Bourne shell scripts. (If you have a development
           | toolchain installed, you probably already have Perl and/or
           | Python and/or Ruby -- so why not script your development
           | workflow in one of those? Or, if everyone is at least running
           | a modern Linux or macOS+Homebrew, why not assume the
           | existence of Bash or Zsh, and write for one of those, instead
           | of Bourne shell?)
           | 
           | Instead, the main places where _large, complex_ shell scripts
           | are _necessary_ , are in:
           | 
           | 1. multi-platform software distribution;
           | 
           | 2. systems-level glue code (think: initrd scripts; sysvinit
           | back when that was a thing; etc) that must be runnable "at
           | early boot" or in a "rescue environment" -- i.e. one that
           | can't guarantee that /usr is mounted, or that /lib is set up
           | correctly to make non-static binaries work, etc. (Or in an
           | "embedded environment" -- in Busybox, /usr doesn't even
           | exist!)
           | 
           | In the first case, the person writing the shell script is
           | _not_ the person running the shell script. Tons of different
           | people run the shell script, on (sometimes drastically)
           | different environments, and these are _not_ developers, and
           | their machines mostly _aren 't_ guaranteed to have anything
           | like a development toolchain installed.
           | 
           | In the second case, despite targeting a single environment,
           | said environment just happens to have a Bourne-shell
           | compatible interpreter as its only scripting environment.
           | (And probably even that was only included because the
           | environment wanted to claim POSIX compatibility, never
           | expecting people to want to script it rather than compiling
           | native tools statically into the environment. Even though
           | most sysadmins who might need to modify these environments,
           | have no idea how to do that.) Mind you, some of these systems
           | -- e.g. UEFI -- _aren 't_ POSIX-compatible at all, but rather
           | require you to "script" them in something totally different,
           | e.g. Forth.
           | 
           | > If you're writing thousands of lines, you can just use any
           | other language, right?
           | 
           | No, not if you can't make any assumptions about the target
           | environment beyond "it's POSIX"; or if the target environment
           | really doesn't offer anything not strictly required by POSIX.
           | There is no POSIX-standard scripting environment other than
           | Bourne shell. (And you can't just ship a binary, because you
           | don't know the target architecture. _Detecting_ the
           | architecture you 've landed on is probably part of what
           | you're trying to do!)
        
         | wging wrote:
         | The niche for such a language would be extremely narrow
         | compared to existing better-than-shell-script alternatives.
         | Wasn't that perl's selling point? Compiling to bash doesn't
         | seem like that much of a better option than shipping (or just
         | requiring implicitly) a $BETTER_LANGUAGE runtime, and writing
         | in that language. (I imagine someone might respond with some
         | carefully constructed scenario where you can only use a shell
         | script, but I'd expect that sort of scenario to be rare.)
         | 
         | My go-to is either Python or Ruby when shell scripts start to
         | get unwieldy - lately it's been Ruby but I'm mentioning Python
         | because I have experience with the type-checking options for
         | Python, and you mentioned that as a benefit. I'm sure someone
         | will point out that type-checking exists for Ruby too (Sorbet,
         | others?); I've just never tried it.
        
           | j1elo wrote:
           | > _I imagine someone might respond with some carefully
           | constructed scenario where you can only use a shell script,
           | but I 'd expect that sort of scenario to be rare._
           | 
           | Not to comment on how frequent this is for other people, but
           | my rare, obscure, and carefully constructed scenario is this
           | one:                   docker run --rm -it ubuntu
        
         | airza wrote:
         | I don't think I understand. Javascript is _required_ in the
         | browser as the end target, but the operating system exposes the
         | APIs which are consumed by bash to do useful work. The normal
         | solution to not wanting to use bash is to... use another
         | language (including, ironically, javascript).
        
           | derefr wrote:
           | Much of the time that people are writing shell scripts,
           | they're writing them not because they prefer shell syntax to
           | that of some other language, but rather because they're
           | creating a script that needs to be widely
           | disseminated/deployed to all sorts of machines with
           | unpredictable toolchain availability.
           | 
           | This is why a large fraction of the shell scripts that exist
           | in the world still hold to Bourne shell syntax, rather than
           | using any of the syntax extensions from its descendant
           | shells: Bourne shell (or at least, something at /bin/sh that
           | interprets Bourne-shell syntax) is part of the POSIX
           | standard. So you can expect any POSIX system -- no matter how
           | weird -- to be able to run (Bourne) shell scripts. You can
           | run them on Alpine. You can run them on Busybox. You can run
           | them on your NAS. You can run them on your router. You can
           | run them in your initramfs, on your Kubernetes nodes, on your
           | Mosix cluster, on your smart TV, on your watch, whatever.
           | They run on Windows; they run on macOS; they (obviously) run
           | on Linux and BSD. _New_ Bourne shell scripts written today,
           | run on 40-year-old operating systems nobody even remembers.
           | 
           | (If you think about it, the whole way that GNU autotools does
           | its job, is by relying on the portability of POSIX-compliant
           | Bourne shell syntax -- i.e. the ./configure script -- to
           | bootstrap out enough of an understanding of whatever system
           | it lands on, to _find_ the tools required to then _probe_ the
           | system for the availability + capabilities of its compilation
           | toolchain.)
           | 
           | For a _small_ example of the type of script I 'm talking
           | about -- see e.g. the script you download+run when you run
           | the command-line on https://rustup.rs:
           | https://github.com/hsivonen/rustup.rs/blob/master/rustup-
           | ini....
           | 
           | For a much better example (that I sadly can't link to), see
           | the install.sh for VMWare Workstation for Linux.
           | 
           | There's absolutely no benefit that these scripts get from
           | being _developed_ directly in POSIX-compiliant Bourne shell
           | syntax, rather than being _developed_ in something that
           | compiles to said syntax; any more than programs for your PC
           | would benefit from being _developed_ directly in ASM, rather
           | than in something that compiles to it.
        
       | latchkey wrote:
       | Intellij has a builtin plugin that integrates with ExplainShell,
       | Shfmt, ShellCheck.
        
       | hutrdvnj wrote:
       | If your problem can be solved neatly with some combination of
       | existing shell utilities, and you just need a bit of glue to join
       | them together, bash is great.
       | 
       | The huge weakness of bash is the data mangling that is more
       | complicated than a relatively simple per-row transformation.
       | Splitting, joining, sorting, min/max of data structures like
       | arrays, lists and trees are trivial in python, not so in bash. If
       | it's not trivially seddable, and awk doesn't help either because
       | you have to rearrange tree like structures, you are about to
       | experience a massive pain, because it's out of scope of even
       | expertly used associative arrays and you will find yourself
       | reinventing the wheel hard using pretty basic tools.
       | 
       | TLDR; As soon as you need to use something more complex than a
       | for loop, switch to Python.
        
       | nickjj wrote:
       | 2 things I'd love to see in a checker would be:
       | 
       | Warn me when I'm using -h instead of --help. When writing
       | persisted scripts it's often more descriptive and self
       | documenting to use long form flags[0] when a tool gives you both
       | options.
       | 
       | Warn me when I mix using "-p 8000:8000" and "-p=8000:8000". I
       | know it's technically not possible to give a definitive answer
       | here because supporting spaces vs equals comes down to the CLI
       | tool itself but you can pick up when you mix the 2 styles and
       | leave it up to the script author to pick a style and stick with
       | it when possible.
       | 
       | I do a lot of shell scripting in my day to day (ops, etc.) and
       | it's always a manual process to give feedback on code reviews
       | when others contribute patches or introduce new scripts.
       | 
       | [0]: https://nickjanetakis.com/blog/when-to-use-long-word-or-
       | shor...
        
         | a-t-0 wrote:
         | @ nickjj Thank you for the input! I have converted your comment
         | into the first issue: https://github.com/TruCol/checkstyle-for-
         | bash/issues/1
        
       ___________________________________________________________________
       (page generated 2022-02-20 23:01 UTC)