Zenity -- 在 Shell Script 中顯示圖形使用者介面
Using GUI in shell script

在編寫與使用者互動的指令稿(shell script)時,傳統的作法都是在 console 中使用一般的文字模式顯示與讀取資料,這種程式在使用起來常常不如圖形使用者介面的程式直覺,而若是要加入圖形使用者介面,程式開發者必須熟悉圖形使用者介面函式庫(例如 GTK 與 Qt 等)的使用方式,並且還要加入大量的程式碼,所以通常小程式都沒有圖形使用者介面。

Zenity 是一個專門用於指令稿(shell script)或命令列(command)的圖形使用者介面工具,他可以很快速的建立下列簡單的圖形介面對話方塊(dialog):
  • 顯示訊息(Message)
    • 錯誤訊息(Error)
    • 一般訊息(Information)
    • 詢問訊息(Question)
    • 警告訊息(Warning)
  • 輸入文字(Text entry)
  • 輸入密碼(Password)
  • 選擇檔案(File selection)
  • 選擇日期(Calendar)
  • 選擇指定的選項(List)
  • 選擇數值或比例(Scale)
  • 顯示進度(Progress) 
  • 選擇顏色(Color Selection)
  • 系統通知區圖示(Notification icon)
有了 Zenity 這個工具,就可以為一般的 shell script 加入圖形使用者介面,提昇程式的品質,以下示範如何使用 Zenity。


顯示訊息(Message)

一般 shell script 中最常用的應該就是顯示一些訊息給使用者,下面這個指令會顯示一個訊息方塊:
zenity --info --text="這是訊息內容" --title="這是標題"
結果為


若是要顯示錯誤訊息可使用:
zenity --error --text="這是錯誤訊息"
結果為


若要顯示警告訊息:
zenity --warning --text="這是警告訊息"
結果為


若要詢問使用者一個簡單的問題,可用:
zenity --question --text="這是一個簡單的問題" --ok-label="沒問題啦" --cancel-label="免談"
結果為


而要取得使用者所選擇的答案,可以在執行完 zenity 之後,藉由讀取 $? 這個 Shell 變數取得 zenity 程式的傳回值,若為 0 代表 OK,若為 1 則代表 CANCEL,完整的程式就像這樣:
zenity --question --text="這是一個簡單的問題" --ok-label="沒問題啦" --cancel-label="免談"
ANS=$?
if [ "$ANS" -eq 0 ]; then
  echo "OK"
else
  echo "CANCEL"
fi


輸入文字(Text entry)

若是要使用者輸入文字,則可使用:
zenity --title "輸入" --entry --text "請輸入文字:"
結果為


使用者輸入文字後,會直接輸出在 console 中,若是要取得輸入的資料,可使用下面這個方式:
TEXT=`zenity --title "輸入" --entry --text "請輸入文字:"`
這樣使用者所輸入的文字就會儲存在 TEXT 這個變數中。

輸入密碼(Password)

若要讓使用者輸入密碼時,不要將密碼直接顯示在螢幕上,可以使用:
zenity --password
結果為



若要取得使用者輸入的密碼,則使用:
PASSWORD=`zenity --password`

選擇檔案(File selection)

zenity 也可以讓使用選擇一個檔案,使用方式為:
zenity --file-selection
結果為


若要取得使用者選擇的檔案:
FILE=`zenity --file-selection`

使用 --filename 可以指定預設的檔案名稱:
zenity --file-selection --filename="myfile.txt"

若要選擇目錄,則加入 --directory 參數:
zenity --file-selection --directory
若要選擇多個檔案或目錄,則可加入 --multiple 參數,並使用 --separator 指定檔案或資料夾的分個字元,例如以逗點分隔:
zenity --file-selection --multiple --separator=","

選擇日期(Calendar)

zenity 除了選擇檔案之外,也可以讓使用選擇一個日期,使用方式為:
zenity --calendar --text="請選擇一個日期"
結果為

預設的日期是當天的日期,也可以加入一些參數來更改:
zenity --calendar --text="請選擇一個日期" --day=19 --month=9 --year=1998

若是要取得使用者所選擇的日期,則可以使用這樣的方式:
DATE=`zenity --calendar --text="請選擇一個日期"`
這樣使用者所選擇的日期就會儲存在 DATE 這個變數中。

選擇指定的選項(List)

zenity 可以讓使用者從指定的一些選項中選擇一個或多個選項,例如要讓使用者選擇一個卡通人物:
zenity --list --text="請選擇一個卡通人物" --column="姓名" "大雄" "多啦A夢" "胖虎" "小福"
結果為


要取得使用者選擇的選項,則可以使用:
SELECTION=`zenity --list --text="請選擇一個卡通人物" --column="姓名" "大雄" "多啦A夢" "胖虎" "小福"`

zenity 也可以顯示多個欄位,提供使用者更多資訊:
zenity --list --text="請選擇一個卡通人物" --print-column=ALL --column="姓名" --column="興趣" "大雄" "睡覺" "多啦A夢" "銅鑼燒" "胖虎" "揍大雄" "小福" "不知道"
結果為


若要讓使用者可以同時選擇多個選項,則可加入 --multiple 參數,另外再配合 --separator 指定分隔輸出結果的字元:
zenity --list --text="請選擇一個卡通人物" --multiple --separator="," --column="姓名" "大雄" "多啦A夢" "胖虎" "小福"

將第一個欄位設定為勾選方塊,並且設定預設打勾的選項:
zenity --list --text="請選擇一個卡通人物" --checklist --column="" --column="姓名" TRUE "大雄" FALSE "多啦A夢" FALSE "胖虎" FALSE "小福"
結果為



將第一個欄位設定為單選(radio)方塊,並且設定預設的選項:
zenity --list --text="請選擇一個卡通人物" --radiolist --column="" --column="姓名" TRUE "大雄" FALSE "多啦A夢" FALSE "胖虎" FALSE "小福"
結果為



選擇數值或比例(Scale)

zenity 可以顯示一個 scale bar 讓使用者很方便的選擇一個數值或比例:
zenity --scale --text="選擇比例"
結果為


可選擇的數值範圍預設是 0 到 100,亦可使用 --min-value 與 --max-value 兩個參數來更改可選擇的範圍,並配合 --value 設定預設的數值(預設為 0,若是設定最小的範圍大於 0,則一定要使用 --value 參數來更改預設數值,否則會出現數值超過界限的錯誤):
zenity --scale --min-value=50 --max-value=500 --value=100 --text="選擇數值"

若要取得使用者選擇的數值,則使用:
VALUE=`zenity --scale --text="選擇比例"`

顯示進度(Progress)

zenity 可以從標準輸入讀入程式執行進度(0 到 100 的數值),然後以圖形顯示出來,這個用法通常是用在一個要跑比較久的程式,將其輸出導給 zenity。這裡我用一個簡單的 Perl Script 當作一個要執行比較久的程式,他會產生 0 到 100 的數值導給 zenity 顯示:
perl -e '$|=1;for(1..10){sleep 1;print ++$i*10,"\n"}'|zenity --progress
結果為


若要讓顯示進度的對話方塊在完成時自動關閉,可加入 --auto-close 參數;當使用者按下取消按鈕時,若要中止(kill)父程序,則可加入 --auto-kill 參數。

選擇顏色(Color Selection)

zenity 可以顯示一個調色盤讓使用者選擇想要的顏色:
zenity --color-selection
結果為


要取得使用者所選擇的顏色也是使用類似的方式:
COLOR=`zenity --color-selection`

系統通知區圖示(Notification icon)

zenity 除了顯示一般的對話方塊之外,也可以用來顯示系統通知區圖示,例如:
zenity --notification --text="這是訊息內容"
結果為


當滑鼠移到通知區的圖示上時,就會顯示訊息內容。


zenity 的功能五花八門,這裡筆者介紹大部分常用到的功能,其餘的部份可以參考其 man page、或是用 --help 參數查詢其使用方式,善用 zenity 這個小工具可以很簡單的將圖形使用者介面加入到一般的指令搞中,非常方便。
本站已經搬家了,欲查看最新的文章,請至 G. T. Wang 新網站