您好,登錄后才能下訂單哦!
核心是case命令,根據用戶的選擇來執行特定的命令。
使用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命令,先清空當前會話的內容。
echo -e選項,可以打印特殊字符。
echo -en選項,會去掉末尾的換行符。這讓菜單看上去更專業,光標會一直行尾等待用戶輸入。
獲取用戶輸入
打印出菜單后,就要等待并獲取用戶輸入。這步使用read命令。這里期望只要單個字符,所以用 -n 選項限制只讀取一個字符。這樣用戶只需要輸入一個數字,并且不用按回車。
創建菜單函數
把上面的部分封裝成一個函數,這樣,在任何時候只要調用函數,就能重現菜單。
樁函數(stub function),是一個空函數,或者只有一個echo語句,說明最終這里需要什么內容:
function diskspace {
clear
echo "Display disk space"
}
這樣,就不需要事先寫出所有函數。菜單能夠直接投入使用,之后在來實現具體的操作。
菜單布局和函數都有了,下面需要創建程序邏輯將二者結合起來。這里就需要case命令。
case命令根據菜單中輸入的字符來調用相應的函數。用默認的case命令字符星號來處理所有不正確的菜單項。
下面就是這個完整的菜單腳本的例子:
#!/bin/bash
# 為腳本創建文本菜單
# --------------------
# 定義函數
# --------------------
# 打印菜單
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
}
# --------------------
# 函數主體
# --------------------
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:
創建文本菜單的過程中,花了一半的精力在建立菜單布局和獲取用戶輸入上。bash shell 提供了一個很容易上手的小工具,可以幫助自動完成這些工作。
select命令只需要一條命令就可以創建出菜單,然后獲取輸入并自動處理。命令格式如下:
select 選項變量 in "選項1" "選項2" "選項3"
do
命令
done
select命令會將每個選項自動加上編號,然后為選項顯示一個由PS3環境變量定義的特殊提示符。所以還要定義PS3環境變量。
這里是一個select命令的示例:
#!/bin/bash
# 為腳本創建文本菜單
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:
使用這個工具可以快速的創建一個簡易的菜單,不過視覺效果就差很多。
dialog包能夠用ANSI轉義控制字符在文本環境中創建標準的窗口對話框。
dialog包提供了很多窗口部件(widget),使用的時候命令格式如下:
dialog --widget parameters
常用的部件如下:
更多窗口部件,后面會詳細列出。
每個dialog部件都提供了兩種形式的輸出:
返回選項
如果選擇了YES或OK,返回退出狀態碼0。如果選擇了Cancel或No,返回退出狀態碼1。可以用標準的$?變量來判斷具體選擇了哪個按鈕。
返回數據
如果是返回數據,則會將數據發送到STDERR。可以用標準的bash shell方法來將STDERR輸出重定向到另一個文件或文件描述符中:
dialog --inputbox "Enter your age: " 10 20 2>age.txt
具體怎么用可以參考下面的示例。
內容比較多,感覺也不一定需要制作這么好的窗口來交換。編寫腳本時記住兩件事:
前面的例子使用dialog包實現的示例代碼:
#!/bin/bash
# 為腳本創建文本窗口菜單
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命令來創建臨時文件,看著挺專業。
另外系統可能默認沒有安裝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
架構 :x86_64
版本 :1.2
發布 :5.20130523.el7
大小 :505 k
源 :installed
來自源:base
簡介 : A utility for creating TTY dialog boxes
網址 :http://invisible-island.net/dialog/dialog.html
協議 : 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部件
部件 | 描述 |
---|---|
calendar | 提供選擇日期的日歷 |
checklist | 顯示多個選項(其中每個選項都能打開或關閉) |
form | 構建一個帶有標簽及文本字段(可以填內容)的表單 |
fselect | 提供一個文件選擇窗口來瀏覽選擇文件 |
gauge | 顯示完成的百分比進度條 |
infobox | 顯示一條消息,但不用等待回應 |
inputbox | 提供一個輸入文本用的文本表單 |
inputmenu | 提供一個可編輯的菜單 |
menu | 顯示可選擇的一系列選項 |
msgbox | 顯示一條消息,并要求用戶選擇OK按鈕 |
pause | 顯示一個進度條來顯示暫停期間的狀態 |
passwordbox | 顯示一個文本框,但會隱藏輸入的文本 |
passwordform | x牧場一個帶標簽和隱藏文本字段的表單 |
radiolist | 提供一組菜單選項,單只能選擇其中一個。就是單選 |
tailbox | 用tail命令在滾動窗口中顯示文件的內容 |
tailboxbg | 更tailbox一樣,但是在后臺模式中運行 |
textbox | 在滾動窗口中顯示文件的內容 |
timebox | 提供一個選擇小時、分鐘和秒的窗口 |
yesno | 提供一條帶有Yes和No按鈕的簡單消息 |
除了標準部件,還可以在dialog命令中定制不同的選項。這些選項可以讓你全面定制窗口外觀和操作。
dialog命令選項
選項 | 描述 |
---|---|
--add-widget | 繼續下個對話框,直到按下Esc或Cancel按鈕 |
--aspect ratio | 指定窗口寬度和高度的寬高比 |
--backtitle title | 指定顯示在屏幕頂部背景上的標題 |
--begin x y | 指定窗口左上角的起始位置 |
--clear | 用默認的對話背景色來清空屏幕內容 |
--colors | 在對話文本中嵌入ANSI色彩編碼 |
--cr-wrap | 在對話文本中允許使用換行符并強制換行 |
--create-rc file | 將示例配置文件的內容復制到指定的file文件中 |
--default-item string | 設定復選列表、表單或菜單對話中的默認項 |
--help | 顯示dialog命令的幫助信息 |
--help-status | 當選定Help按鈕后,在幫助信息后寫入多選列表、單選列表或表單信息 |
--ignore | 忽略dialog不能識別的選項 |
--input-fd fd | 指定STDIN之外的另一個文件描述符 |
--insecure | 在password部件中鍵入內容時顯示星號 |
--item-help | 為多選列表、單選列表或菜單中的每個標號在屏幕底部添加一個幫助欄 |
--keep-window | 不要清除屏幕上顯示過的部件 |
--max-input size | 指定輸入的最大字符串長度。默認為2048 |
--no-collapse | 不要將對話文本中的制表符轉換成空格 |
--no-kill | 將tailbox對話框放到后臺,并禁止該進程的SIGHUP信號 |
--no-shadow | 不要顯示對話窗口的陰影效果 |
--output-fd fd | 指定除STDERR之外的另一個輸出文件描述符 |
--print-maxsize | 將對話窗口的最大尺寸打印到輸出中 |
--print-size | 將對話窗口的大小尺寸打印到輸出中 |
--print-version | 將dialog版本號打印到輸出中 |
--separate-output | 一次一行地輸出checklist部件的結果,不使用引號 |
--separator string | 指定用于分隔部件輸出的字符串 |
--separate-widget string | 指定用于分隔部件輸出的字符串 |
--shadow | 在每個窗口的右下角繪制陰影 |
--single-quoted | 需要時對多選列表的輸出采用單引號 |
--sleep sec | 在處理完對話窗口之后延遲指定的秒數 |
--stderr | 將輸出發送到STDERR(默認行為) |
--stdout | 將輸出發送到STDOUT |
--tab-correct | 將制表符轉換成空格 |
--tab-len n | 指定一個制表符占用的空格數(默認為8) |
--timeout sec | 指定無用戶輸入時,sec秒后退出并返回錯誤代碼 |
--titel title | 指定對話窗口的標題 |
--trim | 從對話文本中刪除前導空格和換行符 |
--visit-items | 修改對話窗口中制表符的停留位置,使其包括選項列表 |
dialog命令選項2
按鈕的選項功能都差不多,單獨列出在這里。可以重寫對話窗口中的任意按鈕標簽:
選項 | 描述 |
---|---|
--cancel-label label | 指定Cancel按鈕的替代標簽 |
--defaultno | 將yes/no對話框的默認答案設為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按鈕指定替代標簽 |
舉例說明
在需要臨時將內容保存到文件的時候,有個特殊命令可以用來創建臨時文件。mktemp命令可以在/tmp目錄中創建一個唯一的臨時文件。shell會創建這個文件,但不用默認的umask值。它會將當前用戶設置為文件的屬主,并且只有屬主有讀寫權限。
默認情況下,mktemp會在當前目錄中創建一個文件。使用命令的時候,需要指定一個文件名模板。模板可以包含任意文本文件名,在文件名末尾加上6個X(幾個X都沒關系,書上建議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
$
這里先創建了幾個臨時文件,干擾一下。使用的時候,創建了文件描述符3來使用,使用完之后關閉了文件描述符。最后精確的把用完的臨時文件給刪除了。
-t選項會強制mktemp命令在系統的臨時目錄創建文件。此時返回的就是創建的文件的全路徑:
$ mktemp -t test3.XXXXXX
/tmp/test3.aPIXIy
$
-d選項則是創建一個臨時目錄。如果要在/tmp目錄下創建臨時目錄,就是-dt:
$ mktemp -d dir.XXXXXX
dir.aBDmsd
$ mktemp -dt dir.XXXXXX
/tmp/dir.pqW927
$
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。