Shell:如何寫一個多選選單的指令碼

不羈的羅恩發表於2021-03-12

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

相關文章