User Tools

Site Tools


documentation:shelldialog

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
documentation:shelldialog [2011/10/11 21:33]
wedge [Resources]
documentation:shelldialog [2011/11/10 19:02] (current)
haas [Objective]
Line 1: Line 1:
 +======Shell Interfaces with Dialog and Whiptail======
  
 +=====Objective=====
 +To learn and understand the dialog and whiptail commands to use them in shell scripts for fun and profit.
 +
 +=====Background=====
 +Once upon a time there was a program called dialog which was used to display text-based widgets in shell scripts. Over time, this software evolved and expanded, seeing code, license, and feature changes.
 +
 +At some point, Whiptail emerged onto the scene. Whiptail is a dialog-like clone which aims to be lighter weight and makes use of the newt library (vs. the ncurses library which dialog uses).
 +
 +=====Usage=====
 +
 +====Dialog Screenshots====
 +It's easy to think that the shell interlace is boring and text-y, but you are wrong! ​ Using the menu command from shell provides graphical-goodness to all of your shell scripts.
 +
 +We've all made menus for programs made in shell, and as hard as you try this is about as fancy as you can get.
 +
 +{{:​documentation:​boringmenu.jpg|}}
 +
 +With one easy command, you can have menus like this!
 +
 +{{:​documentation:​coolmenu.jpg|}}
 +
 +This is actually much easier than you might think - though it will take a bit more code in your shell script to make it functional.
 +
 +====Creating a Menu====
 +To draw this menu, the command line that I used was:
 +<cli>
 +lab46:~$ dialog --menu "Fancy Menu 2" 50 50 100 "​1)"​ "Item 1" "​2)"​ "Item 2" "​3)"​ "Item 3"
 +</​cli>​
 +
 +Pretty simple right? By typing "​dialog"​ by itself, presented with all of the options available for you.  Menu is just the beginning.  ​
 +<​code>​
 +--menu ​        <​text>​ <​height>​ <​width>​ <menu height> <​tag1>​ <​item1>​...
 +</​code>​
 +
 +Taking a look at the menu implementation you can see that we are presented the options that the command will take as an argument. ​
 +
 +<​text>​ - This is the header of the menu box, a title. ​ In my example it is "Fancy Menu 2"
 +
 +<​height>​ - The height of the menu box - 50 in our case
 +
 +<​width>​ - The width of the menu box - again, 50 in our case
 +
 +<​tag1>​ - This is where you choose what the user enters (and the input you will receive into your program). ​ It could be "​A)"​ "​1)"​ or anything else thats intuitive.
 +
 +<​item1>​ - The description of the menu item.  "New Game", "​Launch Missiles",​ or whatever makes sense to your program.
 +
 +
 +====Other Types of Dialogs====
 +We are not just limited to menu applications. ​ A list below gives you an idea of other useful implementations.
 +<​code>​
 +  --calendar ​    <​text>​ <​height>​ <​width>​ <day> <​month>​ <​year>​
 +  --checklist ​   <​text>​ <​height>​ <​width>​ <list height> <​tag1>​ <​item1>​ <​status1>​...
 +  --dselect ​     <​directory>​ <​height>​ <​width>​
 +  --editbox ​     <​file>​ <​height>​ <​width>​
 +  --form ​        <​text>​ <​height>​ <​width>​ <form height> <​label1>​ <​l_y1>​ <​l_x1>​ <​item1>​ <​i_y1>​ <​i_x1>​ <​flen1>​ <​ilen1>​...
 +  --fselect ​     <​filepath>​ <​height>​ <​width>​
 +  --gauge ​       <​text>​ <​height>​ <​width>​ [<​percent>​]
 +  --infobox ​     <​text>​ <​height>​ <​width>​
 +  --inputbox ​    <​text>​ <​height>​ <​width>​ [<​init>​]
 +  --inputmenu ​   <​text>​ <​height>​ <​width>​ <menu height> <​tag1>​ <​item1>​...
 +  --menu ​        <​text>​ <​height>​ <​width>​ <menu height> <​tag1>​ <​item1>​...
 +  --mixedform ​   <​text>​ <​height>​ <​width>​ <form height> <​label1>​ <​l_y1>​ <​l_x1>​ <​item1>​ <​i_y1>​ <​i_x1>​ <​flen1>​ <​ilen1>​ <​itype>​...
 +  --mixedgauge ​  <​text>​ <​height>​ <​width>​ <​percent>​ <​tag1>​ <​item1>​...
 +  --msgbox ​      <​text>​ <​height>​ <​width>​
 +  --passwordbox ​ <​text>​ <​height>​ <​width>​ [<​init>​]
 +  --passwordform <​text>​ <​height>​ <​width>​ <form height> <​label1>​ <​l_y1>​ <​l_x1>​ <​item1>​ <​i_y1>​ <​i_x1>​ <​flen1>​ <​ilen1>​...
 +  --pause ​       <​text>​ <​height>​ <​width>​ <​seconds>​
 +  --progressbox ​ <​height>​ <​width>​
 +  --radiolist ​   <​text>​ <​height>​ <​width>​ <list height> <​tag1>​ <​item1>​ <​status1>​...
 +  --tailbox ​     <​file>​ <​height>​ <​width>​
 +  --tailboxbg ​   <​file>​ <​height>​ <​width>​
 +  --textbox ​     <​file>​ <​height>​ <​width>​
 +  --timebox ​     <​text>​ <​height>​ <​width>​ <​hour>​ <​minute>​ <​second>​
 +  --yesno ​       <​text>​ <​height>​ <​width>​
 +</​code>​
 +
 +====Customizing Dialogs====
 +You can further change the look of dialogs through the options supplied as arguments. ​ Available options are shown below.
 +<​code>​
 +  [--ascii-lines] [--aspect <​ratio>​] [--backtitle <​backtitle>​]
 +  [--begin <y> <x>] [--cancel-label <​str>​] [--clear] [--colors]
 +  [--column-separator <​str>​] [--cr-wrap] [--date-format <​str>​]
 +  [--default-item <​str>​] [--defaultno] [--exit-label <​str>​]
 +  [--extra-button] [--extra-label <​str>​] [--help-button]
 +  [--help-label <​str>​] [--help-status] [--ignore] [--input-fd <fd>]
 +  [--insecure] [--item-help] [--keep-tite] [--keep-window]
 +  [--max-input <n>] [--no-cancel] [--no-collapse] [--no-kill]
 +  [--no-label <​str>​] [--no-lines] [--no-ok] [--no-shadow] [--nook]
 +  [--ok-label <​str>​] [--output-fd <fd>] [--output-separator <​str>​]
 +  [--print-maxsize] [--print-size] [--print-version] [--quoted]
 +  [--scrollbar] [--separate-output] [--separate-widget <​str>​] [--shadow]
 +  [--single-quoted] [--size-err] [--sleep <​secs>​] [--stderr] [--stdout]
 +  [--tab-correct] [--tab-len <n>] [--time-format <​str>​] [--timeout <​secs>​]
 +  [--title <​title>​] [--trace <​file>​] [--trim] [--version] [--visit-items]
 +  [--yes-label <​str>​]
 +</​code>​
 +
 +====Progress Bars (aka gauge boxes)====
 +Dialog/​Whiptail also possess the ability to display impressive-looking progress bars, for use in installing a program or processing a complex task. While amazing, its implementation is a little challenging to the uninitiated.
 +
 +According to the **whiptail(1)** manual page:
 +
 +<​code>​
 +       ​--gauge text height width percent
 +              A gauge box displays a meter along the bottom ​ of  the  box.   ​The ​ meter
 +              indicates ​ a  percentage. ​  New percentages are read from standard input,
 +              one integer per line.  The meter is updated to reflect each new  percent-
 +              age.   ​If ​ stdin is XXX, then subsequent lines up to another XXX are used
 +              for a new prompt. ​ The gauge exits when EOF is reached on stdin.
 +</​code>​
 +
 +The trick here is to notice that gauge boxes work in conjunction with STDIN. That is, they work because you are feeding them information. No information,​ no progress bar.
 +
 +It also literally means having "​XXX"​ being output. That isn't some crazy talk for wildcards... it really wants "​XXX",​ your prompt updating output, then another "​XXX"​.
 +
 +This can lead to very disappointing early results, and it can take some searching to find some actual examples demonstrating how to use this functionality.
 +
 +Here are some working examples to try:
 +
 +===Example 1: Simple 1 to 100 counter in Whiptail===
 +This can be classified as a "nifty but does nothing"​ example... but can open the door to better understanding how this functionality works.
 +
 +We'll simply count to 100 in a loop, have a small delay within, and have whiptail work its magic:
 +
 +<code bash>
 +for((i=1; i<=100; i++)); do
 +    echo "​$i"​
 +    sleep 0.24
 +done | whiptail --backtitle "​Demonstrating the gauge box" --title "​Progress"​ --gauge "​Processing ..." 6 70 0
 +</​code>​
 +
 +===Example 2: Processing a group of data===
 +Where the gauge can really be useful is in processing files or lines within files. We can make use of the prompt update capabilities and get a really impressive output.
 +
 +This example will "​process"​ the files in /dev, updating the prompt while advancing the progress bar towards completion:
 +
 +<code bash>
 +cd /dev
 +cnt="​`/​bin/​ls -1Ad * | wc -l`"
 +pct="​`echo \"​100/​$cnt\"​ | bc -l`"
 +total=0
 +
 +for file in `/bin/ls -1Ad *`; do
 +    total=`echo $total+$pct | bc -l`
 +    echo $total|cut -d'​.'​ -f1
 +    sleep 0.08
 +    echo "​XXX"​
 +    echo "​Processing ... $file"
 +    echo "​XXX"​
 +done | dialog --backtitle "​Demonstrating the gauge box in dialog"​ --title "​Progress"​ --gauge "About to process /dev ..." 6 70 0
 +</​code>​
 +
 +This is an area where the behavior of dialog and whiptail diverge. While you can substitute '​whiptail'​ in for '​dialog',​ you will not get the exact same result. Dialog seems to work especially well in this example.
 +
 +Ideally you'd only want to put a gauge on a time-consuming process, negating any need for an artificially delaying sleep, as has been used in these examples.
 +
 +=====Resources=====
 +
 +  * Gauge Boxes
 +    * http://​en.wikibooks.org/​wiki/​Bash_Shell_Scripting/​Whiptail
 +    * http://​pastebin.com/​MWNrzUaZ
 +    * http://​www.linuxquestions.org/​questions/​programming-9/​dialog-gauge-how-to-display-progress-of-compile-broken-pipe-problem-200614/​
 +    * https://​bugzilla.redhat.com/​show_bug.cgi?​id=620083
 +    * http://​stackoverflow.com/​questions/​1970180/​whiptail-how-to-redirect-output-to-environment-variable
 +
 +<WRAP round note box>
 +Of particular note to whiptail and gauge boxes, the following statement proved insightful:
 +
 +It appears that whiptail(1) writes its control output to the termininal based on the setting of the TERM environment variable. Conseqently,​ you can't use the standard output stream of whiptail(1) to set a variable. Also, whiptail(1) writes the user-input of the input box to the standard error stream so, again, you can't use its standard output stream to set a variable.
 +</​WRAP>​
documentation/shelldialog.txt · Last modified: 2011/11/10 19:02 by haas