Bash case语句无法匹配模式变量,变量赋值失败求助
问题:Bash case语句无法匹配模式变量,command变量未正确赋值
脚本中SearchPattern的长度为40(对应sha1sum的长度),但case语句始终无法正确赋值command变量。以下是原脚本代码及运行输出:
原脚本代码
#!/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
原运行输出
${#SearchPattern}=[40] declare -A shaCommands=([sha256sum]="64" [sha512sum]="128" [sha1sum]="40" [sha384sum]="96" [md5sum]="32" [sha224sum]="56" ) command=[]
问题原因
- case语句实际匹配成功:没有触发默认分支的错误提示,说明
${#SearchPattern}(值为40)已经匹配到了${shaCommands['sha1sum']}对应的分支。 - 赋值逻辑错误:
${!shaCommands['sha1sum']}是Bash的间接引用语法,它会尝试读取名为40的变量的值(因为shaCommands['sha1sum']的值是40),而非通过值反向获取关联数组的键sha1sum。由于不存在名为40的变量,command被赋值为空。
修正方案
方案一:反转关联数组键值对(推荐)
将关联数组改为以长度为键,命令名为值,直接通过长度取值,逻辑更简洁高效:
#!/usr/bin/env bash function run() { local command SearchPattern="a2522866d08d848dd99b5997ad08eb936f68ce91" # 反转键值映射,用校验和长度做键,对应命令做值 local -A lengthToCommand=( [32]='md5sum' [40]='sha1sum' [56]='sha224sum' [64]='sha256sum' [96]='sha384sum' [128]='sha512sum' ) printf "\${#SearchPattern}=[%s]\n" "${#SearchPattern}" declare -p lengthToCommand local target_len=${#SearchPattern} if [[ -n "${lengthToCommand[$target_len]}" ]]; then command="${lengthToCommand[$target_len]}" else printf "unrecognized checksum length=[%d] for [%s]\n" "$target_len" "$SearchPattern" return 1 fi printf "command=[%s]\n" "${command}" } run
方案二:遍历原数组查找对应键
如果需要保留原数组结构,可遍历关联数组的所有键,对比对应的值找到匹配命令:
#!/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 local target_len=${#SearchPattern} # 遍历关联数组的所有键,查找值匹配长度的命令 for cmd in "${!shaCommands[@]}"; do if [[ "${shaCommands[$cmd]}" -eq "$target_len" ]]; then command="$cmd" break fi done if [[ -z "$command" ]]; then printf "unrecognized checksum length=[%d] for [%s]\n" "$target_len" "$SearchPattern" return 1 fi printf "command=[%s]\n" "${command}" } run
修正后运行结果
两种方案都会输出:
${#SearchPattern}=[40] # 对应数组的declare输出 command=[sha1sum]
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

