Skip to content
HomeVideosBooksBlogs
AllTop postsTopics
Podcasts
HistoryListsWatch laterLiked videosFollowing

The videos, books, blogs and podcasts Hacker News keeps recommending, all in one place.

VideosBooksBlogsPodcastsAboutPrivacySettings

Data from Hacker News, HackerTube, HackerBooks, HackerBlogs and Open Library. Credits · Not affiliated with Y Combinator.

HomeVideosBooksBlogsPodcasts
Ctrl K
    A

    Aaron Maxwell

    redsymbol.net · Personal blog · on HN since 2009

    Aaron Maxwell writes about Bash scripting, Python, functional programming and technical career topics.

    Visit blogHN submissions
    ProgrammingOpen Source & Linux
    What HN says

    Commenters often cite his Unofficial Bash Strict Mode article as good practice, while others note that errexit has many caveats.

    Stats for nerds
    51HN people shared it
    30linked in comments
    632story points
    May 2026last shared
    2015people per year2026

    Top posts on HN

    1. 1
      Use the Unofficial Bash Strict Mode (Unless You Love Debugging)
      42 people · 388 points · first shared 2014 · 57 comments on HN
    2. 2
      How “Exit Traps” Can Make Bash Scripts More Robust and Reliable
      5 people · 174 points · first shared 2012 · 38 comments on HN
    3. 3
      Crash course in applied functional programming
      2 people · 58 points · first shared 2009 · 16 comments on HN
    4. 4
      Why I'm Coding in Python 3 (Hint: It's About Gratitude.)
      2 people · 5 points · first shared 2013 · Discussion on HN
    5. 5
      “Exit Traps” Can Make Your Bash Scripts Way More Robust and Reliable
      1 person · 2 points · first shared 2023 · Discussion on HN
    6. 6
      Assertion Injection : Unit Test Design Pattern
      1 person · 2 points · first shared 2010 · Discussion on HN
    7. 7
      Solving Math and Physics Problems You Don't Know How to Solve
      1 person · 1 points · first shared 2026 · Discussion on HN
    8. 8
      Digital Property... Isn't
      1 person · 1 points · first shared 2013 · Discussion on HN
    9. 9
      Meeting People at Tech Meetups
      1 person · 1 points · first shared 2014 · Discussion on HN

    What HN people wrote when they linked it

    • gdavissonJun 2023

      It usually doesn't matter much, but there are some situations where it can matter a lot. For one thing, you can't use seek() on a pipe, so e.g. `cat bigfile | tail` has to read through the entire file to find the end, but `tail bigfile` will read the file backward from the end, completely skipping the irrelevant beginning and middle. With `pv bigfile | whatever`, pv (which is basically a pipeline progress indicator) can tell how big file is and tell you how for through you are as a percentage; with `cat bigfile | pv | whatever`, it has no idea (unless you add a flag to tell it). Also, `cat bigfile | head` will end up killing cat with a SIGPIPE signal after head exits; if you're using something like "Unofficial bash strict mode" [1], this will cause your script to exit prematurely.

      Another sometimes-important difference is that if there are multiple input files, `somecommand file1 file2 file3` can tell what data is coming from which file; with `cat file1 file2 file3 | somecommand` they're all mashed together, and the program has no idea what's coming from where.

      In general, though, I think it's mostly a matter of people's expertise level in using the shell. If you're a beginner, it makes sense to learn one very general way to do things (`cat |`), and use it everywhere. But as you gain expertise, you learn other ways of doing it, and will choose the best method for each specific situation. While `cat |` is usually an ok method to read from a file, it's almost never the best…

    • zbentleyJan 2018

      The thing I wished I had learned earlier is "quick and dirty assertions". If you write lots of functions in Bash, you quickly end up getting tripped up by cases where an argument is omitted and the function does something totally batshit given the missing (empty string) argument. Now, the canonical way to handle this is to put validators on your input, (and make sure those validators don't crash with cryptic errors if someone calling your function is using "set -u") like so:

      function() myfunc {
      local foo="${1:-}"
      if [ -z "$foo" ]; then
      echo "Invalid first parameter!" >&2
      return 127
      fi
      ...
      }

      ...but man, that's time consuming when you have lots of parameters.

      Instead, the quick and dirty way is to just "assert" via [parameter expansion](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html):

      function myfunc() {
      local foo="${1:?First parameter must be provided}"
      ...
      }

      Much quicker, especially when throwing things together in a hurry. It has a gotcha, though: ":?" assertion doesn't cause a function to return early, it shuts down the whole interpreter after outputting the error. So it's more like a true assert() statement than an input validator. If you'd only ever call your function in a subshell, this won't matter (because the subshell will exit early with a nonzero code, big deal), but otherwise it can be a nasty surprise to users when an argument-validation issue inside a function shuts the program…

    • rvenseFeb 2024

      It's cool, nice work! And thank you for sharing it.

      This is just spitballing, you've already solved problem you set out to and get full marks.

      There are always many different ways to do things with bash/shell. Here, you could probably do the entire thing in AWK, which you seem to already be aware of. This might be more readable or it might not.

      If this were a script someone wrote for more general usage, I'd recommend to use the unofficial "bash strict mode"[0], and make sure to check that the awk/sed calls succeed. Shell has a nasty habit of limping along as far as it can if something goes wrong along the way and it's very easy to just end up with bad output and not notice until it's too late.

      Another thing I only recently discovered is envsubst, a tool that's commonly available and tailor-made for substituting variables. You could pipe a template string or pile into that instead of the repetitive calls to echo. What you have here is fine and instantly readable, but if it were three times as long it might not be so nice. Here you could use awk to extract the variables and envsubst to put them into your template.

      Honestly I don't think shell is a good language for writing perfect, robust things anyway. But it's good for exactly what you're doing, though, writing something for yourself that solves a problem without spending too much time on it (although it's fine to spend a lot of time on it if you're learning and/or just enjoying yourself).

      [0]…

    • e12eJan 2017

      On one hand, if you're managing a few servers with shell scripts, you'll invariably end up with a framework of sorts. On the other hand, after a few years playing with bash and posix shell -- I'm fairly certain I'd prefer bash, to posix shell -- it seems rather unlikely you can easily use the same set of scripts for BSD, open solaris and various linux distributions -- if your target is linux, pretty much all distributions ship with bash in base install (just remember to use proper "bang" of #!/usr/bin/env bash or equivalent).

      And shell script is a fickle language -- I'd at least consider using "trap" and/or "set -e", "set -u" -- maybe "set -p" rather than "echo 'what I am about to do'; what I am about to do". See eg: http://redsymbol.net/articles/unofficial-bash-strict-mode/

      I agree that ansible is far from perfect - but I'm not convinced posixcube is a great alternative right now.

      From a brief look at the code, it does look nicely structured and commented, though!

      I've played a bit with the idea of doing something similar (mostly because I'm not convinced all the complexity present in ansible is necessary for my use case -- which appear to be similar to your use-case -- a few small simple server configs).

      I've seen people here on HN recommending some makefiles for deployment (along with simple shell scripts) -- and I've played a bit with using m4 for templates rather than here-documents -- and it looks like that might work fine. Does mean your…

    • imiricApr 2021

      I agree with some of your frustrations, but it's honestly not that bad once you setup your environment properly and get used to some of the quirks.

      > I feel like I spend 45 minutes every time I write a shell script to determine simple things like "is this environment variable set".

      Adopt some best practices[1] and have a template to start new scripts with. ShellCheck also helps with avoiding the most common pitfalls.

      > I find myself reaching for purpose-built tools rather than ad-hoc pipelines

      It helps to distinguish day-to-day interactive work in the shell from writing portable shell scripts that will be robust and require little maintenance for years to come. For the former you want user friendly tools that help you the most with a particular task. For the latter you want to use battle-tested tools with a stable interface that are available on many systems or are preferably built-in to the shell.

      > I am getting more and more frustrated at basic shell mechanics like history handling

      That's mostly a solved problem in many shells. Zsh supports it natively[2].

      I wouldn't want to discourage you from writing your own shell, good luck with that, but there are plenty of good POSIX compatible and alternative shells out there. We can agree that "real" programming languages are much more powerful, safer and friendlier, but plain old shell scripts are the right tool for the job in many situations and shouldn't be ignored at all cost.

      [1]:…

    • StratoscopeApr 2016

      > I once deleted a /lib directory due to a misspelled variable in a script!

      Ah yes, the old "rm -rf $TEMPBASEEDIR/lib" bug. It is so easy to have that happen.

      Or like I did, write a script that assumes a certain environment variable is set outside the script... and then forget to set the variable before running it!

      To prevent these problems, use "set -u" at the top of your bash scripts. This will halt the script instead of silently inserting an empty string if you use an undefined variable.

      "set -e" (halt on nonzero return code) and "set -o pipefail" (propagate error returns through a pipe) are also useful options, or combine them with:

      set -euo pipefail

      Here's a great article that describes these options and some tips for using them:

      http://redsymbol.net/articles/unofficial-bash-strict-mode/

    Related

    Vidar Holenvidarholen.net68 people

    Useless Use of "dd" (2015)

    Vidar Holen
    Personal · last shared 2025
    Mattobox.matto.nl15 people

    We Must Revive Gopherspace (2017)

    Matto
    Personal · last shared 2025
    Andrew Moffatamoffat.github.io50 people

    Show HN: Reimagine the File System

    Andrew Moffat
    Personal · last shared 2026
    Gavin Howardgavinhoward.com43 people

    Is It Even Worth Working on FOSS Anymore?

    Gavin Howard
    Personal · last shared 2026
    fasterthanli.mefasterthanli.me236 people

    A half-hour to learn Rust

    fasterthanli.me
    Personal · last shared 2026
    Zwischenzugszwischenzugs.com66 people

    Things I Wish I'd Known About Bash

    Zwischenzugs
    Personal · last shared 2026
    Russ Coxresearch.swtch.com554 people

    Timeline of the xz open source attack

    Russ Cox
    Personal · last shared 2026
    Ian Bickingblog.ianbicking.org107 people

    Firefox Was Always Enough

    Ian Bicking
    Personal · last shared 2026