this post was submitted on 05 Mar 2025
1578 points (99.0% liked)

Programmer Humor

21027 readers
1338 users here now

Welcome to Programmer Humor!

This is a place where you can post jokes, memes, humor, etc. related to programming!

For sharing awful code theres also Programming Horror.

Rules

founded 2 years ago
MODERATORS
 
you are viewing a single comment's thread
view the rest of the comments
[–] Gobbel2000 11 points 1 day ago (2 children)

So true. Every time I have to look up how to write a bash for loop. Where does the semicolon go? Where is the newline? Is it terminated with done? Or with end? The worst part with bash is that when you do it wrong, most of the time there is no error but something completely wrong happens.

[–] [email protected] 12 points 1 day ago* (last edited 1 day ago) (1 children)

It all makes sense when you think about the way it will be parsed. I prefer to use newlines instead of semicolons to show the blocks more clearly.

for file in *.txt
do
    cat "$file"
done

The do and done serve as the loop block delimiters. Such as { and } in many other languages. The shell parser couldn't know where stuff starts/ends.

Edit: I agree that the then/fi, do/done case/esac are very inconsistent.

Also to fail early and raise errors on uninitialized variables, I recommend to add this to the beginning of your bash scripts:

set -euo pipefail

Or only this for regular sh scripts:

set -eu

-e: Exit on error

-u: Error on access to undefined variable

-o pipefail: Abort pipeline early if any part of it fails.

There is also -x that can be very useful for debugging as it shows a trace of every command and result as it is executed.

[–] [email protected] 0 points 1 day ago* (last edited 1 day ago) (1 children)

set -euo pipefail

Fun fact, if you’re forced to write against POSIX shell, you aren’t allowed to use these options, since they’re not a thing, which is (part of) the reason why for example Google doesn’t allow any shell language but bash, lol.

[–] [email protected] 4 points 1 day ago (1 children)

Btw, all three set options given above are included in POSIX since 2024: https://pubs.opengroup.org/onlinepubs/9799919799/

[–] [email protected] 1 points 1 day ago

Ooh, you’re totally right!! I forgot about that since it’s not in the older versions.

[–] [email protected] 2 points 1 day ago* (last edited 1 day ago)

I can only remember this because I initially didn't learn about xargs


so any time I need to loop over something I tend to use for var in $(cmd) instead of cmd | xargs. It's more verbose but somewhat more flexible IMHO.

So I run loops a lot on the command line, not just in shell scripts.