bash - 选择并执行选择后如何重新显示选择菜单

sup*_*anh 8 bash select

我正在为我的主题制作一个具有 2 个功能的工具脚本:检查更新,重新安装主题

所以这是选择菜单的代码:

PS3='Choose an option: '
options=("Check for update" "Reinstall theme")
select opt in "${options[@]}"
do
     case $opt in
             "Check for update")
                       echo "Checking update"
                               ;;
             "Reinstall theme")
                       echo "Reinstalling"
                               ;;
                               *) echo invalid option;;
     esac
done
Run Code Online (Sandbox Code Playgroud)

运行时显示如下

1) Check for update
2) Reinstall theme
Choose an option:
Run Code Online (Sandbox Code Playgroud)

我输入 1 并回车,执行检查更新命令

问题是当它完成执行脚本时,它重新显示“选择一个选项:”而不是菜单。所以它可以让用户在没有菜单的情况下难以选择(特别是在一个很长的脚本之后)

1) Check for update
2) Reinstall theme
Choose an option: 1
Checking update
Choose an option:
Run Code Online (Sandbox Code Playgroud)

那么如何在执行选项后重新显示菜单

Kus*_*nda 10

我猜你真的想要这样的东西:

check_update () {
    echo "Checking update"
}

reinstall_theme () {
    echo "Reinstalling theme"
}

while true; do
    options=("Check for update" "Reinstall theme")

    echo "Choose an option:"
    select opt in "${options[@]}"; do
        case $REPLY in
            1) check_update; break ;;
            2) reinstall_theme; break ;;
            *) echo "What's that?" >&2
        esac
    done

    echo "Doing other things..."

    echo "Are we done?"
    select opt in "Yes" "No"; do
        case $REPLY in
            1) break 2 ;;
            2) break ;;
            *) echo "Look, it's a simple question..." >&2
        esac
    done
done
Run Code Online (Sandbox Code Playgroud)

我已将任务分离到单独的函数中,以使第一个case语句更小。我还在语句中使用了$REPLY而不是选项字符串,case因为它更短,如果您决定更改它们但忘记在两个地方更新它们也不会中断。我也选择不触摸,PS3因为这可能会影响select脚本中以后的调用。如果我想要一个不同的提示,我会设置一次然后离开它(也​​许PS3="Your choice: ")。这将使包含多个问题的脚本具有更统一的感觉。

我添加了一个外部循环,它会遍历所有内容,直到用户完成。您需要此循环来重新显示第一条select语句中的问题。

我已经添加breakcase语句中,否则除了中断脚本之外没有办法退出。

a 的目的select是从用户那里得到一个问题的答案,而不是真正成为脚本的主要事件循环(本身)。一般来说, a select-case应该只设置一个变量或调用一个函数然后继续。

在第一个中包含“退出”选项的较短版本select

check_update () {
    echo "Checking update"
}

reinstall_theme () {
    echo "Reinstalling theme"
}

while true; do
    options=("Check for update" "Reinstall theme" "Quit")

    echo "Choose an option: "
    select opt in "${options[@]}"; do
        case $REPLY in
            1) check_update; break ;;
            2) reinstall_theme; break ;;
            3) break 2 ;;
            *) echo "What's that?" >&2
        esac
    done
done

echo "Bye bye!"
Run Code Online (Sandbox Code Playgroud)