Essential insights from Hacker News discussions

Bash Strict Mode (2014)

Here are the main themes from the Hacker News discussion:

The Perils and Best Practices of Bash Scripting

A central theme is the inherent complexity and potential pitfalls of using Bash for scripting. While some dismiss it as an "archaic shell," others defend its utility when understood and used correctly.

  • Bash's "Footguns": Several users highlight Bash's tendency to have subtle errors that can cause significant problems.

    • "deathanatos" directly states, "Python is a great scripting language, and won't blow your foot off if you try to iterate through an array."
    • "3eb7988a1663" elaborates on this sentiment: "All languages have foot guns, but bash is on the more explodey end of the scale. It is not senseless to note that if you can use a safer tool, you should consider it."
  • Defending Bash and Proper Usage: Countering the criticism, some argue that many issues stem from improper use and a lack of understanding of Bash's capabilities.

    • "xelxebar" expresses frustration with this perspective: "I kind of hate that every time the topic of shell scripting comes up, we get a troop of comments touting this mindless nonsense. Python has footguns, too. ... Instead of bashing the language, why not learn bash the language?"
    • "xelxebar" also advocates for a data-centric approach: "IME, most of the industry has just absorbed shell programming haphazardly through osmosis, and almost always tries to shove the square pegs of OOP and FP into the round hole that is bash. No wonder people are having a bad time. In contrast, a data-first design that heavily normalizes data into line-oriented tables and passes information around in pipes results in simple, direct code IME. Stop trying to use arrays and embrace data normalization and text."

The Importance of Strict Mode (set -euo pipefail)

A significant portion of the discussion revolves around the use of flags like set -e (errexit), set -u (nounset), and set -o pipefail to make Bash scripts more robust.

  • Advocating for Strict Mode: Many users recommend using these flags as a default for safer scripting.

    • "deathanatos" suggests, "if you must use bash, set -eu -o pipefail; the IFS is new and mildly interesting idea to me."
    • "matheusmoreira" believes, "This honestly should be the default for all scripts. There are so many little annoyances in bash that would make it great if they were changed and improved."
    • "jacob2161" shares their long-standing practice: "I've been writing all my Bash scripts like this for ~15 years and it's definitely the way to go." They also draw a parallel to other languages: "It reminds me when I wrote a lot of Perl: use strict; use warnings;"
  • Criticism and Nuance of Strict Mode: Some users point out the complexities and potential issues with set -e and pipefail.

    • "xelxebar" warns about set -e's unexpected behavior: "I kind of feel like set -o errexit (i.e. set -e) provides enough unexpected semantics that explicit error handling makes more sense." They provide an example where set -e behaves differently inside a function.
    • "chubot" acknowledges the difficulty: "really, you're damned if you do, and damned if you don't, so that is a big reason YSH exists."
    • "aidenn0" questions pipefail's reliability due to potential race conditions.
    • However, "chubot" counters, "All my scripts use pipefail, and I haven't run into problems."
    • "jenders," a self-proclaimed "seasoned shell programmer," views set -euo pipefail as a "bad code smell and an anti-pattern." They argue that experienced shell programmers catch errors "in-band."

Alternatives and Enhancements to Bash

The discussion frequently touches upon better alternatives or ways to improve Bash's deficiencies.

  • Other Scripting Languages: Python is often mentioned as a more user-friendly alternative for scripting.

    • "deathanatos" states, "Python is a great scripting language, and won't blow your foot off if you try to iterate through an array."
    • "heybrendan" suggests, "My personal mantra is if it's over 10~20 lines, I should arguably be using another language, like Python".
  • Next-Generation Shells: Newer shells designed to overcome Bash's limitations are also discussed.

    • "esafak" recommends: "These days I've settled on https://www.nushell.sh/."
    • "tux1968" believes: "I think https://oils.pub/ has a good shot at being the eventual replacement because it has a very strong transition story."
    • "chubot" is a proponent of OSH/YSH and highlights its improvements, especially in error handling.
  • Bash's Limitations and Wishlist Features: Users express desires for features that Bash currently lacks, such as a proper library system.

    • "matheusmoreira" laments: "My number one wishlist feature was a simple library system. Essentially just let me source files by name by searching in some standard user location." They also mention submitting patches for this.
    • "dhamidi" points out that source with PATH offers some similar functionality.
    • "abathur" and "matheusmoreira" discuss implementing a separate search path for sourcing modules.

Tooling and Portability

The conversation also touches on important tools and considerations for writing and running Bash scripts across different environments.

  • Shellcheck: This static analysis tool is praised for helping to identify common Bash pitfalls.

    • "matheusmoreira" notes: "At least we've got shellcheck."
    • "kayson" simply states: "Or use shellcheck: https://www.shellcheck.net/"
    • "burnt-resistor" adds: "Shellcheck isn't a complete solution, and running -e mode is essential to smaller bash files. Shellcheck even knows if a script is in -e mode or not."
  • Shebang Line (#!/bin/bash vs. #!/usr/bin/env bash): There's a discussion about the best practice for the shebang line.

    • "burnt-resistor" argues for #!/usr/bin/env bash for portability.
    • "jacob2161" counters that it relies on /usr/bin/env existing. They also express skepticism about writing truly portable Bash scripts.
  • Verbosity and Clarity: The trade-off between concise and verbose code is discussed, with a preference for clarity in scripts.

    • "jacob2161" prefers long arguments and descriptive code: "I also prefer --long --args everywhere possible and a comment on any short flag unless it's incredibly common."
    • "Waterluvian" agrees, linking verbosity to clarity for scripts.
    • "burnt-resistor" criticizes this verbosity as potentially unportable.
    • "jacob2161" responds that "Clever and compact code is almost never what you want in production code."

Parameter Expansion Nuances

The specific syntax for parameter expansion in Bash is also a point of discussion and contention.

  • Default Values and Undefined Variables: The use of ${var-fallback} and ${var:-fallback} is explained.

    • The original post (as quoted by "deathanatos") explains: "The syntax, ${foo:-fallback} means 'use 'fallback' if foo is unset or is equal to "".'"
    • The manual's "Parameter Expansion" is referenced as the source for understanding these.
  • Quote Handling and IFS: The impact of quoting on word splitting, especially when dealing with arrays, is highlighted.

    • "gorgoiler" demonstrates how double quotes prevent word splitting for array elements: "If the author used double quotes around the array reference then words are kept in tact."
    • The advantage of setting IFS to control word splitting and avoid forgetting quotes is discussed, with "degamad" quoting an argument that "Setting IFS renders this impossible [forgetting quotes]."