Shell:如何寫一個多選菜單的腳本

Blog:部落格園 個人

翻譯自How to Create a Multiple Choice Menu in Bash Scripts

很多方法可以讀取Bash腳本中的用戶輸入。 但是,允許用戶鍵入輸入會帶來一些問題。 主要問題是輸入驗證,您必須在其中考慮所有可能的輸入。 解決此問題的一種簡單方法是為Bash腳本創建一個多選菜單。 使用此方法,您可以定義用戶可以選擇的一組簡單的預定選項。

下文,我們將討論使用select構造和case語句在Bash腳本中創建簡單的多選菜單。

首先,讓我們看一個示例多選菜單腳本,然後我們將其分解並解釋每個部分。

#!/bin/bash
PS3='Choose your favorite food: '
foods=("Pizza" "Pho" "Tacos" "Quit")
select fav in "${foods[@]}"; do
    case $fav in
        "Pizza")
            echo "Americans eat roughly 100 acres of $fav each day!"
	    # optionally call a function or run some code here
            ;;
        "Pho")
            echo "$fav is a Vietnamese soup that is commonly mispronounced like go, instead of duh."
	    # optionally call a function or run some code here
            ;;
        "Tacos")
            echo "According to NationalTacoDay.com, Americans are eating 4.5 billion $fav each year."
	    # optionally call a function or run some code here
	    break
            ;;
	"Quit")
	    echo "User requested exit"
	    exit
	    ;;
        *) echo "invalid option $REPLY";;
    esac
done

仔細觀察以下動圖每個選項的選擇和輸出。 注意選擇某些選項後,它如何要求其他選擇。 但是,當我們選擇Tacos時,它會返回到提示。

Animation of Bash multiple choice menu in action

多選菜單腳本介紹

現在,我們來剖析腳本的每個部分。 這將幫助您了解如何創建多項選擇菜單,以及如何對其進行編輯以適合您的需求。

第一行是shebang,它告訴運行腳本的進程使用哪個解釋器。 在這種情況下,它是bash。

#!/bin/bash

配置輸入提示

下一行設置PS3變數。 這是select語句在從我們的多選菜單中進行選擇時使用的提示。

PS3='Choose your favorite food: '

創建預定選項列表

該行創建了一個可供用戶選擇的選項數組。

foods=("Pizza" "Pho" "Tacos" "Quit")

創建預選菜單

在這裡,我們開始創建菜單的選擇構造。 在這一行中,我們告訴select選擇從foods數組創建菜單。 我們還將在$fav變數中設置用戶選擇。 select構造的語法類似於for循環,這就是為什麼您在末尾看到do語句的原因。

select fav in "${foods[@]}"; do

使用case語句創建更多可靠的選項

case語句使您可以有選擇地執行與第一個匹配模式相對應的命令。 例如,如果我們從多項選擇菜單中選擇Pizza,它將執行與該單詞相對應的命令列表。

在case語句中,我們有開頭節。 這告訴案例搜索與$fav變數的值匹配的選項。

case $fav in

接下來,我們有一堆子句概述了每個選項。 它從一個或多個要匹配的選項開始,然後在找到匹配項時運行該程式碼。 我們所有的子句都以;;結尾,這是終止字元串。此子句說明,如果$fav的值與Pizza相匹配,請運行echo命令。

        "Pizza")
            echo "Americans eat roughly 100 acres of $fav each day!"
	    # optionally call a function or run some code here
            ;;

在上面的動圖,我要求您觀察所做的選擇以及每個更改的輸出。 我想指出的是,每次選擇一個選項時,程式碼都會運行,然後將您帶回到select循環中。

Tacos子句顯示了如何添加break命令。 這告訴腳本脫離循環。 因此,如果選擇Pizza,它將運行與該選擇相對應的echo命令,然後要求另一個選擇(因為沒有break命令)。 但是,如果選擇Tacos,它將運行與Tacos子句相對應的echo命令,然後中斷循環並繼續執行腳本。

        "Tacos")
            echo "According to NationalTacoDay.com, Americans are eating 4.5 billion $fav each year."
	    # optionally call a function or run some code here
	    break
            ;;

此行將匹配並告知這是無效的輸入。

 *) echo "invalid option $REPLY";;

示例:

[savona@putor TMP]$ ./test-menu.sh 
1) Pizza
2) Pho
3) Tacos
4) Quit
Choose your favorite food: 8
invalid option 8
Choose your favorite food: 

關閉select循環和case語句

在所有match子句之後,我們以esac結束case語句,而esac是反寫的的。 這類似於以fi結束if語句。

    esac

最後一行關閉用do打開的select語句。

done