You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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=[]

问题原因

  1. case语句实际匹配成功:没有触发默认分支的错误提示,说明${#SearchPattern}(值为40)已经匹配到了${shaCommands['sha1sum']}对应的分支。
  2. 赋值逻辑错误:${!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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:05:00