2015/11/9

Text Based User Interface (TUI)

如果有用過 Linux CLI interface 的使用者,一定會看過有些 script 指令執行之後,不是直接以文字的方式輸出結果,而是跳出一個圖形界面,這種圖形界面,並不像 X Windows 那麼華麗,對使用者來說,確實獲得了不少幫助,尤其是一些比較少用到的指令,或是忘了放在哪裡的設定檔要修改的時候。

舉例來說,在 centos 如果要修改網路卡、Gateway、DNS,可以直接去修改網路卡跟 DNS 的設定檔,不常修改這些設定的使用者有另一個選擇,就是直接在 console 執行 system-config-network ,就可以看到 GUI 使用者界面,省去了不少功夫。

這種圖形界面稱為 Text-based user interface,也稱為 terminal user interface,比較複雜的 TUI 還可以做出一個完整的檔案管理員。

但有時候,我們只需要一個簡單的圖形化的使用者互動界面,這時候可以借助 dialog 的幫助,讓我們能夠快速地建造一個 TUI 界面的程式。

Dialog

Dialog 是可以直接在 console 中,產生 TUI 的 library,我們可以直接找到有關 dialog 的範例。

以 centos 來說,如果沒有安裝 dialog,可以直接用 yum install dialog 將 dialog 安裝起來。然後到 /usr/share/doc/dialog-1.1/samples/ 目錄中,可以看到很多範例程式。

[root@server ~]# cd /usr/share/doc/dialog-1.1/samples/
[root@server samples]# ls
calendar          dselect          gauge2          inputmenu3        msgbox3             slackware.rc
calendar2         editbox          gauge3          inputmenu4        msgbox4-8bit        sourcemage.rc
calendar2-stdout  editbox2         infobox         inputmenu-stdout  msgbox4-eucjp       suse.rc
calendar3         editbox3         infobox1        killall           msgbox4-utf8        tailbox
calendar3-stdout  editbox-utf8     infobox2        listing           msgbox5             tailboxbg
calendar-stdout   form1            infobox3        menubox           msgbox6             tailboxbg1
checklist         form1-both       infobox4        menubox1          msgbox6a            tailboxbg2
checklist1        form1-extra      infobox5        menubox10         msgbox-help         testdata-8bit
checklist10       form1-help       infobox6        menubox2          password            textbox
checklist2        form1-utf8       inputbox        menubox3          password1           textbox2
checklist3        form2            inputbox1       menubox4          password2           textbox3
checklist4        form3            inputbox2       menubox5          passwordform1       textbox.txt
checklist5        form4            inputbox3       menubox6          passwordform1-utf8  timebox
checklist6        form5            inputbox4       menubox7          pause               timebox2
checklist7        form6            inputbox5       menubox8          pause-help          timebox2-stdout
checklist8        fselect          inputbox6-8bit  menubox-8bit      progress            timebox-stdout
checklist-8bit    fselect1         inputbox6-utf8  menubox9          progress2           wheel
checklist9        fselect1-stdout  inputbox7       menubox-utf8      radiolist           whiptail.rc
checklist9.txt    fselect2         inputbox-both   mixedform         radiolist10         yesno
checklist-utf8    fselect2-stdout  inputbox-extra  mixedform2        radiolist2          yesno2
copifuncs         fselect-stdout   inputbox-help   mixedgauge        radiolist3          yesno3
copismall         gauge            inputmenu       msgbox            radiolist4          yesno-both
debian.rc         gauge0           inputmenu1      msgbox1           README              yesno-extra
dialog.py         gauge0-input-fd  inputmenu2      msgbox2           rotated-data        yesno-help

由 dialog 手冊,我們可看到 dialog 支援的 dialog box 有以下這些:
calendar, checklist, dselect, editbox, form, fselect, gauge, infobox, inputbox, inputmenu, menu, mixedform, mixedgauge, msgbox (message), passwordbox, passwordform, pause, progressbox, radiolist, tailbox, tailboxbg, textbox, timebox, and yesno (yes/no).

Sample 1

連續產生三個 yesno dialog,後面的 yesno 會直接覆蓋在前面的 yesno 上面。

dialog                         --begin 2 2 --yesno "" 0 0 \
    --and-widget               --begin 4 4 --yesno "" 0 0 \
    --and-widget               --begin 6 6 --yesno "" 0 0

產生三個 yesno dialog,但新的 dialog 出現前,會先把前面的清空,所以最後只會顯示第三個 yesno。

dialog           --clear       --begin 2 2 --yesno "" 0 0 \
    --and-widget --clear       --begin 4 4 --yesno "" 0 0 \
    --and-widget               --begin 6 6 --yesno "" 0 0

跟第一個範例的結果很像,後面的 yesno 會蓋掉前面的 yesno,差別是跳出這三個 yesno 之後,畫面上顯示的是第一個 yesno。

dialog           --keep-window --begin 2 2 --yesno "" 0 0 \
    --and-widget --keep-window --begin 4 4 --yesno "" 0 0 \
    --and-widget               --begin 6 6 --yesno "" 0 0

顯示第一跟第三個 yesno。

dialog           --keep-window --begin 2 2 --yesno "" 0 0 \
    --and-widget --clear       --begin 4 4 --yesno "" 0 0 \
    --and-widget               --begin 6 6 --yesno "" 0 0

Sample 2

  • hello world

    dialog --title 'Message' --msgbox 'Hello, world!' 5 20
    


  • yesno

    dialog --title "Message"  --yesno "Are you having fun?" 6 25
    


  • wait 4 seconds and exit

    dialog --infobox "Please wait" 10 30 ; sleep 4
    
  • inputbox - get result in file named "answer"

    dialog --inputbox "Enter your name:" 8 40 2>answer
    


  • textbox: file content display with scroll bar

    dialog --textbox /etc/profile 22 70
    


  • option 三選一

    dialog --menu "Choose one:" 10 30 3 1 red 2 green 3 blue
    


  • options 多選

    dialog --checklist "Choose toppings:" 10 40 3 \
          1 Cheese on \
          2 "Tomato Sauce" on \
          3 Anchovies off
    


  • radiolist

    dialog --backtitle "CPU Selection" \
    --radiolist "Select CPU type:" 10 40 4 \
          1 386SX off \
          2 386DX on \
          3 486SX off \
          4 486DX off
    


  • guage: progress bar
    將以下的 script 放到一個 test.sh 中,直接執行這個 script

    #!/bin/bash
    { for I in 10 20 30 40 50 60 70 80 90 \
        80 70 60 50 40 30 20 10 0; do
     echo $I
     sleep 1
    done
    echo; } | dialog --guage "A guage demo" 6 70 0
    


References

Linux程序設計入門 - Dialog
在 shell script 中使用圖形式互動元件 - dialog 與 zenity 使用範例
Dialog Screenshots

dialog man page

Dialog: An Introductory Tutorial

Linux Apprentice: Improve Bash Shell Scripts Using Dialog

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

ncurses