this post was submitted on 15 Jan 2025
571 points (98.3% liked)

linuxmemes

21826 readers
1008 users here now

Hint: :q!


Sister communities:


Community rules (click to expand)

1. Follow the site-wide rules

2. Be civil
  • Understand the difference between a joke and an insult.
  • Do not harrass or attack members of the community for any reason.
  • Leave remarks of "peasantry" to the PCMR community. If you dislike an OS/service/application, attack the thing you dislike, not the individuals who use it. Some people may not have a choice.
  • Bigotry will not be tolerated.
  • These rules are somewhat loosened when the subject is a public figure. Still, do not attack their person or incite harrassment.
  • 3. Post Linux-related content
  • Including Unix and BSD.
  • Non-Linux content is acceptable as long as it makes a reference to Linux. For example, the poorly made mockery of sudo in Windows.
  • No porn. Even if you watch it on a Linux machine.
  • 4. No recent reposts
  • Everybody uses Arch btw, can't quit Vim, <loves/tolerates/hates> systemd, and wants to interject for a moment. You can stop now.
  •  

    Please report posts and comments that break these rules!


    Important: never execute code or follow advice that you don't understand or can't verify, especially here. The word of the day is credibility. This is a meme community -- even the most helpful comments might just be shitposts that can damage your system. Be aware, be smart, don't fork-bomb your computer.

    founded 2 years ago
    MODERATORS
     

    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.

    you are viewing a single comment's thread
    view the rest of the comments
    [–] Badabinski@kbin.earth 88 points 1 day ago (15 children)

    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.

    [–] Aquila@sh.itjust.works 16 points 1 day ago* (last edited 1 day ago) (7 children)

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

    [–] Badabinski@kbin.earth 12 points 1 day ago (6 children)

    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.

    [–] jkercher@programming.dev 1 points 1 day ago* (last edited 1 day ago)

    Woah, that ((i++)) triggered a memory I forgot about. I spent hours trying to figure out what fucked up my $? one day.

    When I finally figured it out: "You've got to be kidding me."

    When i fixed with ((++i)): "SERIOUSLY! WTAF Bash!"

    load more comments (5 replies)
    load more comments (5 replies)
    load more comments (12 replies)