TIL: Some surprising code execution sources in bash
https://yossarian.net/til/post/some-surprising-code-execution-sources-in-bash
@yossarian The use of '[[' is the problem. That's an evaluating comparison and is as dangerous as 'eval' (as shown). All scripts should be using just the single '['. Using '[[' is for compatibility with ancient shells.
@kees @yossarian uh, good to know. I'm pretty sure at some point I've been told (maybe by some linting tool?) that [[ is preferrable to [.
@hanno @yossarian Yeah this was a common recommendation long ago to "avoid bash-isms" for compatibility. Since then busybox and dash (the common non-bash "/bin/sh" instances) grew '[' support either internally or via /usr/bin/[
@kees @yossarian I'm confused, this tells me [[ is the bash'ism, and [ the posix thing: https://mywiki.wooledge.org/BashFAQ/031
@hanno @yossarian Ah, I may have it backwards then, but '[' remains the safe one.
@kees @hanno @yossarian `[` is the POSIX one, but it has silly semantics around strings, which is you you end up doing stuff like `[ "x$foo" -ne "x" ]` to test non-emptiness.
`[[` on the other hand behaves "sanely", but it's definitely a bashism and not portable.
@kees @hanno @yossarian There are many misconceptions in this thread. The test command `[` is well-defined[1] and works as expected. It can be argued that `[[` doesn't work as expected since it introduces semantics which are incompatible with the rest of the shell language.
@flameeyes Your example is wrong, `-ne` is for math. You can test for null or unset simply: `[ "$foo" ]`.
Neither option is unsafe, OP issue stems from array indexing in bash, specifically.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html
@jntesteves @kees @hanno @yossarian I blame not having had my coffee for that `-ne`
@jntesteves @hanno @yossarian @flameeyes
Ah! That's why this doesn't work:
$ foo='0$(echo bad >&2) + 7' $ if [[ "$foo" -eq 0 ]]; then echo zero; fi
-bash: [[: 0$(echo bad >&2) + 7: syntax error: invalid arithmetic operator (error token is "$(echo bad >&2) + 7")
@jntesteves @kees @hanno @yossarian @flameeyes Jup, the x-in-variable expansion was for buggy implementations of `[` but it can be implemented correctly without requiring this workaround.
As @jntesteves said, `[` is well-defined. Arguably, `[[` is a bit "safer" for word expansions (after all, that's what it was designed to be better at), but you can do `[` quite safely.