Explanation for newbies:

  • Shell is the programming language that you use when you open a terminal on linux or mac os. Well, actually “shell” is a family of languages with many different implementations (bash, dash, ash, zsh, ksh, fish, …)

  • Writing programs in shell (called “shell scripts”) is a harrowing experience because the language is optimized for interactive use at a terminal, not writing extensive applications

  • The two lines in the meme change the shell’s behavior to be slightly less headache-inducing for the programmer:

    • set -euo pipefail is the short form of the following three commands:
      • set -e: exit on the first command that fails, rather than plowing through ignoring all errors
      • set -u: treat references to undefined variables as errors
      • set -o pipefail: If a command piped into another command fails, treat that as an error
    • export LC_ALL=C tells other programs to not do weird things depending on locale. For example, it forces seq to output numbers with a period as the decimal separator, even on systems where coma is the default decimal separator (russian, dutch, etc.).
  • The title text references “posix”, which is a document that standardizes, among other things, what features a shell must have. Posix does not require a shell to implement pipefail, so if you want your script to run on as many different platforms as possible, then you cannot use that feature.

  • Aquila@sh.itjust.works
    link
    fedilink
    arrow-up
    0
    ·
    edit-2
    3 days ago

    Putting or die “blah blah” after every line in your script seems much less elegant than op’s solution

    • Badabinski@kbin.earth
      link
      fedilink
      arrow-up
      1
      ·
      3 days ago

      The issue with set -e is that it’s hideously broken and inconsistent. Let me copy the examples from the wiki I linked.


      Or, “so you think set -e is OK, huh?”

      Exercise 1: why doesn’t this example print anything?

      #!/usr/bin/env bash
      set -e
      i=0
      let i++
      echo "i is $i"
      

      Exercise 2: why does this one sometimes appear to work? In which versions of bash does it work, and in which versions does it fail?

      #!/usr/bin/env bash
      set -e
      i=0
      ((i++))
      echo "i is $i"
      

      Exercise 3: why aren’t these two scripts identical?

      #!/usr/bin/env bash
      set -e
      test -d nosuchdir && echo no dir
      echo survived 
      
      #!/usr/bin/env bash
      set -e
      f() { test -d nosuchdir && echo no dir; }
      f
      echo survived
      

      Exercise 4: why aren’t these two scripts identical?

      set -e
      f() { test -d nosuchdir && echo no dir; }
      f
      echo survived
      
      set -e
      f() { if test -d nosuchdir; then echo no dir; fi; }
      f
      echo survived
      

      Exercise 5: under what conditions will this fail?

      set -e
      read -r foo < configfile
      

      And now, back to your regularly scheduled comment reply.

      set -e would absolutely be more elegant if it worked in a way that was easy to understand. I would be shouting its praises from my rooftop if it could make Bash into less of a pile of flaming plop. Unfortunately , set -e is, by necessity, a labyrinthian mess of fucked up hacks.

      Let me leave you with a allegory about set -e copied directly from that same wiki page. It’s too long for me to post it in this comment, so I’ll respond to myself.