This conundrum is stumping me. Why can't bash's case stmt match the pattern variable and properly assign the array's index value to the command variable?
Script Code:
#!/usr/bin/env bash
function run() {
local command SearchPattern="a2522866d08d848dd99b5997ad08eb936f68ce91"
local -A shaCommands=(
['md5sum']=32
['sha1sum']=40
['sha224sum']=56
['sha256sum']=64
['sha384sum']=96
['sha512sum']=128
)
printf "\${#SearchPattern}=[%s]\n" "${#SearchPattern}"
declare -p shaCommands
case ${#SearchPattern} in
${shaCommands['md5sum']} ) command="${!shaCommands['md5sum']}" ;;
${shaCommands['sha1sum']} ) command="${!shaCommands['sha1sum']}" ;;
${shaCommands['sha224sum']} ) command="${!shaCommands['sha224sum']}" ;;
${shaCommands['sha256sum']} ) command="${!shaCommands['sha256sum']}" ;;
${shaCommands['sha384sum']} ) command="${!shaCommands['sha384sum']}" ;;
${shaCommands['sha512sum']} ) command="${!shaCommands['sha512sum']}" ;;
* ) printf "unrecognized checksum length=[%d] for [%s]\n" \
"${#SearchPattern}" "${SearchPattern}"
return $Fail
;;
esac
printf "command=[%s]\n" "${command}"
}
run
The output shows the case patterns are never matched - it should match on the ${shaCommands['sha1sum']} ) pattern - so $command is never assigned ...
${#SearchPattern}=[40]
declare -A shaCommands=([sha256sum]="64" [sha512sum]="128" [sha1sum]="40" [sha384sum]="96" [md5sum]="32" [sha224sum]="56" )
command=[]
The case statement matches (you can confirm with set -x
), but the assignment to command
after the match is empty. "${!shaCommands['sha1sum']}"
does not get the index of the array element like you want it to, because that expansion to get the indices of the array only works for ${!name[@]}
or ${!name[*]}
according to the manual.
${!name[@]}
${!name[*]}
If name is an array variable, expands to the list of array indices (keys) assigned in name.
If name is not an array, expands to 0 if name is set and null otherwise.
When ‘@’ is used and the expansion appears within double quotes, each key
expands to a separate word.
In other cases, ${!var}
is an indirect reference (see Parameter Expansion) where the value of var
is used as the name of a variable to reference. ${shaCommands['sha1sum']}
has a value of 40, so ${!shaCommands['sha1sum']}
is interpreted as ${40}
which is not set in your command, so you get an empty string from the expansion.
You can simply use command=sha1sum
instead. You're already hardcoding the key that you use to access the array, so your attempted solution isn't really any more robust than just hardcoding the command value.