this post was submitted on 15 Jan 2025
567 points (98.6% liked)

linuxmemes

21817 readers
1038 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
    [–] [email protected] 4 points 11 hours ago* (last edited 11 hours ago) (1 children)

    My only issue is -u. How do you print help text if your required parameters are always filled. There's no way to test for -z if the shell bails on the first line.

    Edit: though I guess you could initialise your vars with bad defaults, and test for those.

    [–] [email protected] 9 points 11 hours ago (2 children)
    #!/bin/bash
    set -euo pipefail
    
    if [[ -z "${1:-}" ]]
    then
      echo "we need an argument!" >&2
      exit 1
    fi
    
    [–] [email protected] 2 points 5 hours ago

    God I love bash. There's always something to learn.

    my logical steps

    • #! yup
    • if sure!
    • [[ -z makes sense
    • ${1:-} WHAT IN SATANS UNDERPANTS.... parameter expansion I think... reads docs ... default value! shit that's nice.

    it's like buying a really simple generic car then getting excited because it actually has a spare and cupholders.

    [–] [email protected] 3 points 10 hours ago* (last edited 10 hours ago) (1 children)

    That's good, but if you like to name your arguments first before testing them, then it falls apart

    #!/bin/bash
    set -euo pipefail
    
    myarg=$1
    
    if [[ -z "${myarg}" ]]
    then
      echo "we need an argument!" >&2
      exit 1
    fi
    

    This fails. The solution is to do myarg=${1:-} and then test

    Edit: Oh, I just saw you did that initialisation in the if statement. Take your trophy and leave.

    [–] [email protected] 2 points 9 hours ago* (last edited 9 hours ago) (1 children)

    Yeah, another way to do it is

    #!/bin/bash
    set -euo pipefail
    
    if [[ $# -lt 1 ]]
    then
      echo "Usage: $0 argument1" >&2
      exit 1
    fi
    

    i.e. just count arguments. Related, fish has kind of the orthogonal situation here, where you can name arguments in a better way, but there's no set -u

    function foo --argument-names bar
      ...
    end
    

    in the end my conclusion is that argument handling in shells is generally bad. Add in historic workarounds like if [ "x" = "x$1" ] and it's clear shells have always been Shortcut City


    Side note: One point I have to award to Perl for using eq/lt/gt/etc for string comparisons and ==/</> for numeric comparisons. In shells it's reversed for some reason? The absolute state of things when I can point to Perl as an example of something that did it better

    [–] [email protected] 2 points 9 hours ago (1 children)

    Perl is the original GOAT! It took a look at shell, realised it could do (slightly) better, and forged its own hacky path!

    [–] [email protected] 2 points 9 hours ago* (last edited 9 hours ago)

    I was about to say, half the things people write complex shell scripts for, I'll just do in something like Perl, Ruby, Python, even node/TS, because they have actual type systems and readability. And library support. Always situation-dependent though.