Bash

bash - 選擇並執行選擇後如何重新顯示選擇菜單

  • March 14, 2022

我正在為我的主題製作一個具有 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

執行的時候是這樣的

1) Check for update
2) Reinstall theme
Choose an option:

我輸入 1 並輸入,執行檢查更新命令

問題是當它完成執行腳本時,它重新顯示“選擇一個選項:”而不是菜單。所以它會讓使用者在沒有菜單的情況下難以選擇(尤其是在很長的腳本之後)

1) Check for update
2) Reinstall theme
Choose an option: 1
Checking update
Choose an option:

那麼如何在執行選項後重新顯示菜單

我猜你真的想要這樣的東西:

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

我已將任務分離到單獨的函式中,以使第一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!"

引用自:https://unix.stackexchange.com/questions/293340