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.

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

    set -euo pipefail is, in my opinion, an antipattern. This page does a really good job of explaining why. pipefail is occasionally useful, but should be toggled on and off as needed, not left on. IMO, people should just write shell the way they write go, handling every command that could fail individually. it’s easy if you write a die function like this:

    die () {
      message="$1"; shift
      return_code="${1:-1}"
      printf '%s\n' "$message" 1>&2
      exit "$return_code"
    }
    
    # we should exit if, say, cd fails
    cd /tmp || die "Failed to cd /tmp while attempting to scrozzle foo $foo"
    # downloading something? handle the error. Don't like ternary syntax? use if
    if ! wget https://someheinousbullshit.com/"$foo"; then
      die "failed to get unscrozzled foo $foo"
    fi
    

    It only takes a little bit of extra effort to handle the errors individually, and you get much more reliable shell scripts. To replace -u, just use shellcheck with your editor when writing scripts. I’d also highly recommend https://mywiki.wooledge.org/ as a resource for all things POSIX shell or Bash.

    • renzev@lemmy.worldOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      1 month ago

      I’ve been meaning to learn how to avoid using pipefail, thanks for the info!