溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

shell 創(chuàng)建文本菜單

發(fā)布時間:2020-08-08 00:26:39 來源:網(wǎng)絡(luò) 閱讀:383 作者:騎士救兵 欄目:系統(tǒng)運維

創(chuàng)建文本菜單

核心是case命令,根據(jù)用戶的選擇來執(zhí)行特定的命令。

創(chuàng)建菜單布局

使用echo命令打印字符,生成一個菜單,還可以包括標題等信息:

clear
echo
# -e 選項,打印特殊字符
echo -e "\t\t\tSys Admin Menu\n"
echo -e "\t1. Display disk space"
echo -e "\t2. Display logged on users"
echo -e "\t3. Display memory usage"
echo -e "\t0. Exit program\n\n"
# -en 會去掉末尾的換行符,光標會留在行尾
echo -en "\t\tEnter option: "
# 獲取用戶輸入,只期望獲取到單個字符,-n選擇限制只讀1個字符,并且用戶不用回車
read -n 1 option

clear命令,先清空當前會話的內(nèi)容。
echo -e選項,可以打印特殊字符。
echo -en選項,會去掉末尾的換行符。這讓菜單看上去更專業(yè),光標會一直行尾等待用戶輸入。

獲取用戶輸入
打印出菜單后,就要等待并獲取用戶輸入。這步使用read命令。這里期望只要單個字符,所以用 -n 選項限制只讀取一個字符。這樣用戶只需要輸入一個數(shù)字,并且不用按回車。

創(chuàng)建菜單函數(shù)
把上面的部分封裝成一個函數(shù),這樣,在任何時候只要調(diào)用函數(shù),就能重現(xiàn)菜單。

創(chuàng)建樁函數(shù)

樁函數(shù)(stub function),是一個空函數(shù),或者只有一個echo語句,說明最終這里需要什么內(nèi)容:

function diskspace {
    clear
    echo "Display disk space"
}

這樣,就不需要事先寫出所有函數(shù)。菜單能夠直接投入使用,之后在來實現(xiàn)具體的操作。

添加菜單邏輯

菜單布局和函數(shù)都有了,下面需要創(chuàng)建程序邏輯將二者結(jié)合起來。這里就需要case命令。
case命令根據(jù)菜單中輸入的字符來調(diào)用相應(yīng)的函數(shù)。用默認的case命令字符星號來處理所有不正確的菜單項。
下面就是這個完整的菜單腳本的例子:

#!/bin/bash
# 為腳本創(chuàng)建文本菜單

# --------------------
# 定義函數(shù)
# --------------------

# 打印菜單
function menu {
    clear
    echo
    # -e 選項,打印特殊字符
    echo -e "\t\t\tSys Admin Menu\n"
    echo -e "\t1. Display disk space"
    echo -e "\t2. Display logged on users"
    echo -e "\t3. Display memory usage"
    echo -e "\t0. Exit program\n\n"
    # -en 會去掉末尾的換行符,光標會留在行尾
    echo -en "\t\tEnter option: "
    # 獲取用戶輸入,只期望獲取到單個字符,-n選擇限制只讀1個字符,并且用戶不用回車
    read -n 1 option
}

function diskspace {
    clear
    df -k
}

function whoseon {
    clear
    who
}

function menusage {
    clear
    cat /proc/meminfo
}

# --------------------
# 函數(shù)主體
# --------------------
while [ 1 ]
do
    # 菜單邏輯
    menu
    case $option in
    0)
        break ;;
    1)
        diskspace ;;
    2)
        whoseon ;;
    3)
        menusage ;;
    *)
        clear
        echo "Wrong selection";;
    esac
    echo -en "\n\n\t\tHit any key to continue"
    read -n 1 line
done
clear

菜單的顯示效果如下:


                        Sys Admin Menu

        1. Display disk space
        2. Display logged on users
        3. Display memory usage
        0. Exit program

                Enter option: 

使用 select 命令

創(chuàng)建文本菜單的過程中,花了一半的精力在建立菜單布局和獲取用戶輸入上。bash shell 提供了一個很容易上手的小工具,可以幫助自動完成這些工作。

select命令只需要一條命令就可以創(chuàng)建出菜單,然后獲取輸入并自動處理。命令格式如下:

select 選項變量 in "選項1" "選項2" "選項3"
do
    命令
done

select命令會將每個選項自動加上編號,然后為選項顯示一個由PS3環(huán)境變量定義的特殊提示符。所以還要定義PS3環(huán)境變量。

示例代碼

這里是一個select命令的示例:

#!/bin/bash
# 為腳本創(chuàng)建文本菜單

function diskspace {
    clear
    df -k
}

function whoseon {
    clear
    who
}

function menusage {
    clear
    cat /proc/meminfo
}

PS3="Enter option: "
select option in "Display disk space" "Display logged on users" \
"Display memory usage" "Exit program"
do
    case $option in
    "Exit program")
        break ;;
    "Display disk space")
        diskspace ;;
    "Display logged on users")
        whoseon ;;
    "Display memory usage")
        menusage ;;
    *)
        clear
        echo "Wrong selection";;
    esac
done

菜單效果如下:

$ menu2.sh 
1) Display disk space       3) Display memory usage
2) Display logged on users  4) Exit program
Enter option: 

使用這個工具可以快速的創(chuàng)建一個簡易的菜單,不過視覺效果就差很多。

制作窗口(dialog包)

dialog包能夠用ANSI轉(zhuǎn)義控制字符在文本環(huán)境中創(chuàng)建標準的窗口對話框。

窗口部件

dialog包提供了很多窗口部件(widget),使用的時候命令格式如下:

dialog --widget parameters

常用的部件如下:

  1. msgbox部件:在窗口中顯示一條簡單的消息,會有一個OK按鈕
  2. yesno部件:允許用戶對窗口中顯示的問題選擇yes或no,會有兩個按鈕
  3. inputbox部件:提供一個簡單的文本框區(qū)域來輸入文本
  4. textbox部件:可以在窗口中顯示大量信息,會生成一個滾動窗口
  5. menu部件:創(chuàng)建文本菜單,需要為每個選項提供一個選擇標號和顯示文本
  6. fselect部件:可以用來瀏覽文件和文件夾

更多窗口部件,后面會詳細列出。

獲取部件的輸出

每個dialog部件都提供了兩種形式的輸出:

  • 使用退出狀態(tài)碼
  • 使用STDERR

返回選項
如果選擇了YES或OK,返回退出狀態(tài)碼0。如果選擇了Cancel或No,返回退出狀態(tài)碼1??梢杂脴藴实??變量來判斷具體選擇了哪個按鈕。

返回數(shù)據(jù)
如果是返回數(shù)據(jù),則會將數(shù)據(jù)發(fā)送到STDERR。可以用標準的bash shell方法來將STDERR輸出重定向到另一個文件或文件描述符中:

dialog --inputbox "Enter your age: " 10 20 2>age.txt

具體怎么用可以參考下面的示例。

示例代碼

內(nèi)容比較多,感覺也不一定需要制作這么好的窗口來交換。編寫腳本時記住兩件事:

  • 如果有按鈕,檢查dialog命令的退出狀態(tài)碼
  • 否則就重定向STDERR來獲取輸出的值

前面的例子使用dialog包實現(xiàn)的示例代碼:

#!/bin/bash
# 為腳本創(chuàng)建文本窗口菜單

temp=$(mktemp -t test.XXXXXX)
temp2=$(mktemp -t test2.XXXXXX)

function diskspace {
    df -k > $temp
    dialog --textbox $temp 20 60
}

function whoseon {
    who > $temp
    dialog --textbox $temp 20 50
}

function menusage {
    cat /proc/meminfo > $temp
    dialog --textbox $temp 20 50
}

while [ 1 ]
do
dialog --menu "Sys Admin Menu" 20 30 10 \
1 "Display disk space" \
2 "Display logged on users" \
3 "Display memory usage" \
0 "Exit program" 2> $temp2
if [ $? -eq 1 ]
then
    break
fi

selection=$(cat $temp2)
case $selection in
0)
    break ;;
1)
    diskspace ;;
2)
    whoseon ;;
3)
    menusage ;;
*)
    dialog --msgbox "Wrong selection" 10 30
esac
done
rm -f $temp 2> /dev/null
rm -f $temp2 2> /dev/null

這里用到了臨時文件,并且使用mktemp命令來創(chuàng)建臨時文件,看著挺專業(yè)。

安裝dialog包

另外系統(tǒng)可能默認沒有安裝dialog包,要運行這個腳本,需要先安裝dialog包:

[root@Ansible ~]# yum info dialog
已加載插件:fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
已安裝的軟件包
名稱    :dialog
架構(gòu)    :x86_64
版本    :1.2
發(fā)布    :5.20130523.el7
大小    :505 k
源    :installed
來自源:base
簡介    : A utility for creating TTY dialog boxes
網(wǎng)址    :http://invisible-island.net/dialog/dialog.html
協(xié)議    : LGPLv2
描述    : Dialog is a utility that allows you to show dialog boxes (containing
         : questions or messages) in TTY (text mode) interfaces.  Dialog is called
         : from within a shell script.  The following dialog boxes are implemented:
         : yes/no, menu, input, message, text, info, checklist, radiolist, and
         : gauge.
         : 
         : Install dialog if you would like to create TTY dialog boxes.

dialog部件詳表

dialog部件

部件 描述
calendar 提供選擇日期的日歷
checklist 顯示多個選項(其中每個選項都能打開或關(guān)閉)
form 構(gòu)建一個帶有標簽及文本字段(可以填內(nèi)容)的表單
fselect 提供一個文件選擇窗口來瀏覽選擇文件
gauge 顯示完成的百分比進度條
infobox 顯示一條消息,但不用等待回應(yīng)
inputbox 提供一個輸入文本用的文本表單
inputmenu 提供一個可編輯的菜單
menu 顯示可選擇的一系列選項
msgbox 顯示一條消息,并要求用戶選擇OK按鈕
pause 顯示一個進度條來顯示暫停期間的狀態(tài)
passwordbox 顯示一個文本框,但會隱藏輸入的文本
passwordform x牧場一個帶標簽和隱藏文本字段的表單
radiolist 提供一組菜單選項,單只能選擇其中一個。就是單選
tailbox 用tail命令在滾動窗口中顯示文件的內(nèi)容
tailboxbg 更tailbox一樣,但是在后臺模式中運行
textbox 在滾動窗口中顯示文件的內(nèi)容
timebox 提供一個選擇小時、分鐘和秒的窗口
yesno 提供一條帶有Yes和No按鈕的簡單消息

dialog選項

除了標準部件,還可以在dialog命令中定制不同的選項。這些選項可以讓你全面定制窗口外觀和操作。

dialog命令選項

選項 描述
--add-widget 繼續(xù)下個對話框,直到按下Esc或Cancel按鈕
--aspect ratio 指定窗口寬度和高度的寬高比
--backtitle title 指定顯示在屏幕頂部背景上的標題
--begin x y 指定窗口左上角的起始位置
--clear 用默認的對話背景色來清空屏幕內(nèi)容
--colors 在對話文本中嵌入ANSI色彩編碼
--cr-wrap 在對話文本中允許使用換行符并強制換行
--create-rc file 將示例配置文件的內(nèi)容復(fù)制到指定的file文件中
--default-item string 設(shè)定復(fù)選列表、表單或菜單對話中的默認項
--help 顯示dialog命令的幫助信息
--help-status 當選定Help按鈕后,在幫助信息后寫入多選列表、單選列表或表單信息
--ignore 忽略dialog不能識別的選項
--input-fd fd 指定STDIN之外的另一個文件描述符
--insecure 在password部件中鍵入內(nèi)容時顯示星號
--item-help 為多選列表、單選列表或菜單中的每個標號在屏幕底部添加一個幫助欄
--keep-window 不要清除屏幕上顯示過的部件
--max-input size 指定輸入的最大字符串長度。默認為2048
--no-collapse 不要將對話文本中的制表符轉(zhuǎn)換成空格
--no-kill 將tailbox對話框放到后臺,并禁止該進程的SIGHUP信號
--no-shadow 不要顯示對話窗口的陰影效果
--output-fd fd 指定除STDERR之外的另一個輸出文件描述符
--print-maxsize 將對話窗口的最大尺寸打印到輸出中
--print-size 將對話窗口的大小尺寸打印到輸出中
--print-version 將dialog版本號打印到輸出中
--separate-output 一次一行地輸出checklist部件的結(jié)果,不使用引號
--separator string 指定用于分隔部件輸出的字符串
--separate-widget string 指定用于分隔部件輸出的字符串
--shadow 在每個窗口的右下角繪制陰影
--single-quoted 需要時對多選列表的輸出采用單引號
--sleep sec 在處理完對話窗口之后延遲指定的秒數(shù)
--stderr 將輸出發(fā)送到STDERR(默認行為)
--stdout 將輸出發(fā)送到STDOUT
--tab-correct 將制表符轉(zhuǎn)換成空格
--tab-len n 指定一個制表符占用的空格數(shù)(默認為8)
--timeout sec 指定無用戶輸入時,sec秒后退出并返回錯誤代碼
--titel title 指定對話窗口的標題
--trim 從對話文本中刪除前導空格和換行符
--visit-items 修改對話窗口中制表符的停留位置,使其包括選項列表

dialog命令選項2
按鈕的選項功能都差不多,單獨列出在這里??梢灾貙憣υ挻翱谥械娜我獍粹o標簽:

選項 描述
--cancel-label label 指定Cancel按鈕的替代標簽
--defaultno 將yes/no對話框的默認答案設(shè)為No
--exit-label label 指定Exit按鈕的替代標簽
--extra-button 在OK按鈕和Cancel按鈕之間顯示一個額外按鈕
--extra-label label 指定額外按鈕的替代標簽
--help-button 在OK按鈕和Cancel按鈕后顯示一個Help按鈕
--help-label label 指定Help按鈕的替代標簽
--nocancel 隱藏Cancel按鈕
--no-lable label 為No按鈕指定替代標簽
--ok-label label 指定OK按鈕的替代標簽
--yes-label label 為Yes按鈕指定替代標簽

舉例說明

  • --title選項,允許你設(shè)置出現(xiàn)在窗口頂部的部件標題。
  • --backtitle選項,是為腳本中的菜單創(chuàng)建公共標題的簡便辦法。
  • --create-rc選項,dialog命令支持運行時配置。該命令會根據(jù)配置文件模板創(chuàng)建一份配置文件。

創(chuàng)建本地臨時文件(mktemp)

在需要臨時將內(nèi)容保存到文件的時候,有個特殊命令可以用來創(chuàng)建臨時文件。mktemp命令可以在/tmp目錄中創(chuàng)建一個唯一的臨時文件。shell會創(chuàng)建這個文件,但不用默認的umask值。它會將當前用戶設(shè)置為文件的屬主,并且只有屬主有讀寫權(quán)限。

創(chuàng)建文件

默認情況下,mktemp會在當前目錄中創(chuàng)建一個文件。使用命令的時候,需要指定一個文件名模板。模板可以包含任意文本文件名,在文件名末尾加上6個X(幾個X都沒關(guān)系,書上建議6位):

$ mktemp test1.XXXXXX
test1.Acrugq
$ ls -al test1*
-rw-------. 1 steed steed 0 12月 12 14:26 test1.Acrugq
$ 

mktemp命令會用6位字符碼替換這6個X,從而保證文件名在目錄中是唯一的。

在腳本中使用

在腳本中使用mktemp命令時,需要將文件名保存到變量中,這樣就能在后面的腳本中引用了:

$ mktemp test2.XXXXXX
test2.leOFBZ
$ mktemp test2.XXXXXX
test2.5kDbKn
$ mktemp test2.XXXXXX
test2.domeOC
$ mktemp test2.XXXXXX
test2.CJX702
$ tempfile=$(mktemp test2.XXXXXX)
$ exec 3>>$tempfile
$ echo "test2 Line1" >&3
$ echo "TEST2 LINE2" >&3
$ exec 3>&-
$ cat $tempfile
test2 Line1
TEST2 LINE2
$ ls -al test2*
-rw-------. 1 steed steed  0 12月 12 14:41 test2.5kDbKn
-rw-------. 1 steed steed  0 12月 12 14:41 test2.CJX702
-rw-------. 1 steed steed  0 12月 12 14:41 test2.domeOC
-rw-------. 1 steed steed  0 12月 12 14:41 test2.leOFBZ
-rw-------. 1 steed steed 24 12月 12 14:41 test2.tMVTwN
$ rm -f $tempfile 2> /dev/null
$ ls -al test2*
-rw-------. 1 steed steed 0 12月 12 14:41 test2.5kDbKn
-rw-------. 1 steed steed 0 12月 12 14:41 test2.CJX702
-rw-------. 1 steed steed 0 12月 12 14:41 test2.domeOC
-rw-------. 1 steed steed 0 12月 12 14:41 test2.leOFBZ
$ 

這里先創(chuàng)建了幾個臨時文件,干擾一下。使用的時候,創(chuàng)建了文件描述符3來使用,使用完之后關(guān)閉了文件描述符。最后精確的把用完的臨時文件給刪除了。

在/tmp目錄創(chuàng)建臨時文件

-t選項會強制mktemp命令在系統(tǒng)的臨時目錄創(chuàng)建文件。此時返回的就是創(chuàng)建的文件的全路徑:

$ mktemp -t test3.XXXXXX
/tmp/test3.aPIXIy
$ 

創(chuàng)建臨時目錄

-d選項則是創(chuàng)建一個臨時目錄。如果要在/tmp目錄下創(chuàng)建臨時目錄,就是-dt:

$ mktemp -d dir.XXXXXX
dir.aBDmsd
$ mktemp -dt dir.XXXXXX
/tmp/dir.pqW927
$ 
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI