Shellcheck is great. Unfortunately, its checks pale at the idiosyncrasies of per-version bashism.
For example:
set u
ignored_users=()
for i in "${ignored_users[@]}"; do
echo "$i"
done
passes shellcheck's checks, however bash <= 4.3 will crash with "bash: ignored_users[@]: unbound variable". Therefore, set -u isn't available to use in this (valid) use-case.Shellcheck also doesn't catch the expansion of variables as key names in testing assoc arrays:
declare -A my_array
un='$anything'
[[ -v my_array["$un"] ]] && return 1
will will fail as "my_array: bad array subscript" because "$un" gets expanded to "$anything", which on a second pass, gets expanded to "", making the check [[ -v my_array[] ]]. Even worse, a value of un='$(huh)'
actually gets executed: [[ -v my_array["$un"] ]] && return 1
-bash: huh: command not found
Here's another one: in versions older than 4.3 (maybe?) these -v checks don't even work: $ declare -A my_array
$ my_array["key"]=1
$ [[ -v 'my_array["key"]' ]] && echo exists
$ [[ -v my_array["key"] ]] && echo exists
$ [[ -v $my_array["key"] ]] && echo exists
$ [[ -v "$my_array["key"]" ]] && echo exists
$ bash --version
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
I've recently been documenting some of this on my website: https://joshua.hu/more-fun-with-bash-ssh-and-ssh-keygen-vers...