select:接受未列出的char输入



我使用bash select来创建一个多选对话框,当我在两个现有选项之间添加新选项时,选项编号会自动调整。

select choice in command1 command2 command3; do
    $choice
    break
done

为了显示与命令本身不同的内容,我被告知要声明一个关联数组

declare -A choices=(
    [Option 1]=command1
    [Option 2]=command2
    [Option 3]=command3
)
select choice in "${!choices[@]}" exit ; do
    [[ $choice == exit ]] && break
    ${choices[$choice]}
done

我不喜欢这种方式的一点是,exit的选项被视为一个编号的选择。我想实现类似的目标

PS3="Select the desired option (q to quit): "

并使select除了接受123之外,还接受q作为有效输入。

关联数组会导致输入用作索引这一事实出现问题,因此我切换到嵌套的case。这样,我也不必声明单独的函数来存储多个命令

PS3="Select the desired option (q to quit): "
select choice in "Option 1" "Option 2" "Option 3"; do
    case $choice in
        "Option 1") command1a
                    command1b
                    break;;
        "Option 2") command2a
                    command2b
                    break;;
        "Option 3") command3a
                    command3b
                    break;;
        q)          echo "Bye!"
                    break;;
    esac
done

现在不存在关于非数字(或超范围(输入的问题,但是作为输入的q仍然没有被识别。它属于default的情况,如果我已经定义了它,就执行*),如果我没有定义它,就简单地再次提示。

有什么方法可以实现我想要做的事情吗?

只需使用(检查的内容($REPLY变量。

示例:

declare -A choices=(
    [Show the date]=show_date
    [Print calendar]=print_cal
    [Say hello]=say_hello
)
show_date() {
    date
}
print_cal() {
    cal
}
say_hello() {
    echo "Hello $USER"
}
PS3="Select the desired option (q to quit): "
select choice in "${!choices[@]}"
do
    case "$choice" in
    '') # handling the invalid entry - e.g. the "q"
        # in a case of an invalid entry, the $choice is en empty(!) string
        # checking the content of the entered line can be done using the $REPLY
        case "$REPLY" in
            q|Q) echo "Bye, bye - quitting...."; exit;;
            *) echo "INVALID choice <$REPLY> - try again";;
        esac
        ;;
    *)
        #valid user input
        ${choices[$choice]}
        ;;
    esac
done

或者更短,但没有那么灵活的

declare -A choices=(
    [Show the date]=show_date
    [Print calendar]=print_cal
    [Say hello]=say_hello
)
show_date() {
    date
}
print_cal() {
    cal
}
say_hello() {
    echo "Hello $USER"
}
PS3="Select the desired option (q to quit): "
select choice in "${!choices[@]}"
do
    case "$REPLY" in
    q|Q) echo "Bye, bye - quitting...."; exit;;
    1|2|3) ${choices[$choice]} ;;
    *) echo "INVALID choice <$REPLY> - try again";;
    esac
done

相关内容

  • 没有找到相关文章

最新更新