Hacker News new | ask | show | jobs
by dundarious 1109 days ago
There is almost never a good reason to use constructs like eval in any language (and it exists in many languages), just like there are barely any good reasons to use constructs like system() in C. It appears acme.sh was running eval. I haven't looked into it, but the most common reason I see eval in use is because people don't know that you do it much simpler/more directly by just geting the shell to run commands that are variables with no issue, e.g., `doit() { printf "running: %s\\n" "$*" ; "$@" ; } ; doit ls /` which works in POSIX sh, no bashisms. (Obviously you should only call it with at least the first argument being trusted)

But shell is really not hard if people stick to a few easy guidelines:

- quote all var expansion, e.g., "$var" not $var or ${var} (very rare to need otherwise, and never for untrusted data)

- use "$@" to perfectly forward arguments (not $@, not $*, not "$*" except when you want to turn many arguments into one)

- don't use eval

- use `set -eu` and explicitly handle functions/commands that may benignly return/exit non-zero, e.g., `diff -U10 ./a ./b || true`

- use printf on untrusted strings instead of echo (just use it generally, I say), e.g., printf %s\\n "$var" instead of echo "$var". One of the few times you want to use "$*" is with printf though, e.g., printf %s\\n "$*" instead of echo "$@". Try them out, easy to see why, as with one thing to format and multiple arguments, `printf %s\\n "$@"` is equivalent to `for i in "$@" ; do printf %s\\n "$i" ; done`

- when using xargs, use -0 if available, or at least -d\\n if available (busybox doesn't have it for example). also usually want to use -r

1 comments

And then run shellcheck because even those of us that painful have this seared into our brains make mistakes.

Or just use a scripting language that eliminates many of these headaches (nushell) or a real programming language.

I get it, I really do. At least now I have nushell for some sanity, but I still find myself constantly writing a shell script and then realizing after a few iterations that I should've just written in nushell/Rust.

As a thought experiment, how many places rolled out acme.sh to prod and didn't bother code reviewing it or running it through shellcheck?

Every language exists on this spectrum, and pretty much every language is clustered near shell. All languages require you to be "principled" in a few key areas, and many projects (open source and closed source) don't do a great job at that.

At least shell is good at a specific and very useful thing (sequences and pipelines of other commands), and is already installed on most machines -- even windows nowadays since almost everyone has git installed. My "build system" for C projects is just doing the following from pwsh: `& "$env:GIT_INSTALL_ROOT\bin\bash.exe" .\build.sh`

Most software is not great. That is the issue.

I'm happy (and spoiled) that I live in a world where I get to use reliable software and not worry about it being inaccessible. With a single nix command, I'm dropped in an environment with secrets mounted by a single age key, with all programs and configuration exactly as I want. It's trivial for me to "just switch" to nushell/rust and not worry about such things. And nushell and rust are not clustered near shell for the aspects I'm talking about in this discussion.

"bash is everywhere" is just more lipstick on the pig, in my strong opinion.