This is a consulting report on csdn today. I think it is very practical, and I have never paid attention to shell and the potential of graphics before. So I would like to take a note.
By Martin Streicher, http://sd.csdn.net/a/20110420/296194.html
Dialog Unix: Graphical Applications created using shell scripts
Introduction: the command line is not suitable for every user. In fact, some users may feel comfortable only when holding the mouse. To use only shell to meet these users or build desktop applications, you can add some guis to your scripts. Here are some specific practices.
If you enter a crowded data center, you may hear chats about "shebangs", slashes, dots, roots, pipelines, ports, and so on. Speaking of UNIX, you will undoubtedly understand local terms-Unix acronyms, command names, shortcuts, options, file names, and dialects-and feel at home. Like other artists, usung users have a wide range of terms to describe their work details.
Not everyone talks about Unix. In fact, some people may find that the command line is complex and frustrating. In addition, you may not want to pin all command lines to temporary or inexperienced users. To help those who are not used to using command lines, or build a custom solution around shell, you can build a GUI for your scripts. With this tool, dialog and zenity are two tools worth mentioning (see references) -You can use the dialog box, file browser, and other common "wing" controls and technologies to interact with your users. In fact, the dialog box provides more natural dialogs: You raise a question, request a response, and respond accordingly.
This "Dialog UNIX" explores dialog and zenity and shows how to convert any script into a convincing GUI application. For traditional text-based interfaces using dialog, zenity provides a modern Windows desktop.
Add a dialog box to any shell script
A command line utility usually provides enough options to fully control each call. Some DOS commands may enable or disable a feature, while other DOS commands may process parameters, such as the name list. On the command line, you present (almost) All information in front and then execute the task. Graphics applications are quite different. The selection is made through menus, check boxes, and file browsers. A graphic application receives a bit of information, processes it, And then typically requires more information. It is said that GUI applications are event-driven.
The dialog utility spans two worlds. Call the utility when you need input from the user, and then return to your script to continue processing any provided data. In other words, if you write a script to use dialog, you may ignore the command line parameter, but use dialog to send a prompt when necessary.
If your system lacks the dialog utility, you can easily use the Package Manager that comes with the current version to install it, or you can compile it directly through the source code. For example, if your system uses aptitude, you can run the following command to install the dialog:
- sudo apt-get install dialog
Otherwise, you must compile the source code to download the code on the web site of Thomas Dickey (see references) and run the following three typical commands :. /configure & make install:
- $ wget http://invisible-island.net/datafiles/release/dialog.tar.gz
- $ tar xzf dialog.tar.gz
- $ cd dialog-1.1-20100428
- $ ./configure
- $ make
- $ sudo make install
After the installation is complete, you should have a new utility named dialog in your path. Enter man dialog to view the bundled document.
Dialog is easy to use: It is just another Unix Command. You can use the Command Option to display the selected dialog box, capture the result, and execute some logic based on the value. Some variants of dialog directly place command results in special shell state variables $? , You should save or ask the variable immediately after the dialog command exits (because the value of a subsequent command will change immediately ). In addition, the more complex dialog command variants usually set shell state variables and generate other results at the same time. To simplify things, dialog provides the -- stdout option to send the results to the standard output, so it is easy to through command evaluation (a combination of commands with left quotation marks and value assignment statements ).
For example, the dialog -- yesno command is one of the simplest variants. It raises a question, prompts a yes or no response, and returns $? 0 or 1 in, depending on whether the user selects "yes" or "no ". You can test $? And execute some conditional code. Here is a working code segment that you can add to the shell script:
- dialog --yesno "Do you want to continue?" 0 0
- rc=$?
- if [ "${rc}" == "0" ]; then
- echo Yes
- else
- echo No
- fi
The -- yesno option requires at least three parameters: the question text and the height and width of the dialog box, which are measured by rows and columns. If you do not need a specific size, you can always use 0 for the height or width to automatically adjust the dialog box size. (There are options for placing a window in the lower left corner of the window .) Figure 1 shows the running -- yesno.
Figure 1. -- yesno operation
Dialog option -- Calendar presents a calendar to allow users to select a specific date. If you select a date and click OK, the command returns 0. However, if you click Cancel, the command returns 1. In addition, if you click OK, the Command sends the selected date as the standard output. Here is an example of using the command to evaluate the generation Date:
- RESULT=`dialog --stdout --title "CALENDAR"
- --calendar "Please choose a date..." 0 0 9 1 2010`
- retval=$?
-- The title option uses the next parameter to add a title to the dialog box and can be used for any dialog command. Very similar to -- yesno, you provide some text to remind users. Next, option 0 0 specifies the automatic height and width again, Option 9 1 2010 indicates the initial day, month, and year displayed in the calendar, respectively. Tab and arrow keys change the calendar and select a date. After the dialog box exits, if retval is 0, the result value is the selected date. Figure 2 shows the calendar dialog box.
Figure 2. Calendar dialog box
The dialog command provides most of the controls commonly found in graphic applications:
-- Infobox only displays information: it does not require any input. The information box is still simply on the screen. To extend its display, place a sleep command before it and the next command.
-- Input collects a single input response. You may use this command to collect your user name or zip code.
-- Textbox displays the content of a text file. If the file exceeds the vertical height of the dialog box, a control supports Simple up and down scrolling.
-- Menu and -- radiolist provide a selection list for users to select. The two dialogs are functionally equivalent, but slightly different visual styles are used to better simulate what a GUI may display. In particular, the -- radiolist command (& nbsp;) is used to simulate single-choice buttons.
-- Checklist: displays a list of projects that can be enabled or disabled independently.
The output of each dialog variant is different, either a single value, or a column with quotation marks separated by spaces. For example, -- checklist is a good control used to select one or more options. It issues a column of enclosed values, each of which is related to an enabled option. The following shows an operation example:
- RESULT=`dialog --stdout
- --checklist "Enable the account options you want:" 10 40 3 /
- 1 "Home directory" on /
- 2 "Signature file" off /
- 3 "Simple password" off`
The backslash (/) at the end of lines 1, 2, and 3 is a continuation mark; everything from result to off is a command. If the home directory and simple password are enabled, $ result is "1" "3 ". -- The checklist parameter is the height and width, and the number of list elements in any time (if some items are blocked, you can scroll to view these items ), and configuration options (where each option is a value), a description, initially enabled or disabled.
You can enter dialog -- help at any time to view the General List, and enter dialog to view specific options. There are countless usage of dialog.
Pixel? Use zenity.
Zenity is a UNIX desktop, just as dialog is a simple terminal window. You can use zenity to open the GTK + dialog box from any shell script. In fact, zenity and dialog have many identical functions. The only difference is that zenity works in an X Window System Environment. Zenity is bound with Gnome. If you do not run gnome, you can install zenity separately (however, you also need to install a large number of GTK + libraries ). You can also download the source code of zenity from the gnome project page (see references for links ).
The following is a simple example. Command:
- zenity --question --text "Do you want to continue?"
The generated result is shown in figure 3. (The demo machine is running Ubuntu 10 .) If you click OK, the command returns 0. Otherwise, it returns 1.
Figure 3. a simple problem
Like dialog, zenity has many options-even more than dialog-but the options are well-known. You may find that zenity is more advantageous than dialog, especially because most computer users have certain X desktops.
Zenity provides the same many controls as dialog. Here is a code snippet for collecting names:
- ENTRY=`zenity --entry --text "Please enter your name"
- --entry-text "Your name" --title "Enter your name"
- if [ $? == 0 ]; then
- zenity --info --text "Hello $ENTRY/!"
- fi
Again, if the exit code of zenity is 0, the entry has the name of someone. Here is an example of a calendar that is rewritten to use zenity:
- DATE=`zenity --calendar --day "9" --month "1" --year "2010" --format "%Y-%m-%d"
- if [ $? == 0 ]; then
- echo $DATE
- fi
Although zenity is more detailed-for example, there are separate options for years, months, and days-Other DOS commands prevent you from remembering the exact order of parameter usage. Zenity calendar also allows you to specify the output format, that is, use the standard strftime () code. The result of this command is similar to January 9, 2010.
Zenity also provides a process table to display the status of an operation. It reads data from standard input row by row. If the prefix of a row is a pound sign (#), the text is updated to the row text. If a row contains only one number, the percentage is updated to this number. Listing 1 shows an example in the zenity document.
List 1. zenity Process Table
- #!/bin/sh
- (
- echo "10" ; sleep 1
- echo "# Updating mail logs" ; sleep 1
- echo "20" ; sleep 1
- echo "# Resetting cron jobs" ; sleep 1
- echo "50" ; sleep 1
- echo "This line will just be ignored" ; sleep 1
- echo "75" ; sleep 1
- echo "# Rebooting system" ; sleep 1
- echo "100" ; sleep 1
- ) |
- zenity --progress /
- --title="Update System Logs" /
- --text="Scanning mail logs..." /
- --percentage=0
-
- if [ "$?" = -1 ] ; then
- zenity --error /
- --text="Update canceled."
- fi
Sub-shell (included in parentheses) executes a series of tasks-in this example, albeit sleep latency-and sends the output to a zenity Process Table through a pipeline. Before each step, sub-shell sends a number to promote the process table. Each -- Percentage 0 starts from 0 and then sends a string starting with # To change the status. Therefore, the Process Table works by marking the script following the steps. If zenity's exit code is-1, click the cancel button.
Again, use dialog or zenity to replace the code that has referenced the command line parameters with the dialog box. With a small idea, you can convert your shell script into a first-class desktop citizen.
Other advanced tools
Sometimes, you may find that your requirements are beyond the functional range of shell scripts and dialog and zenity tools. In those instances, you may switch to C/C ++ and build local applications for the desktop, but you can also use advanced scripting languages to bind to languages with many powerful GUI frameworks.
A combination is Ruby binding between the ruby scripting language and the wxWidgets framework. Ruby is object-oriented, expressive, and concise and runs on most operating systems. The wxWidgets framework can also be used on mainstream platforms, including Mac OS X, windows, Linux, and UNIX. Since both are portable, you can write an application once in Ruby and then run it everywhere. Another simpler choice is shoes. Although it is not as rich as wxWidgets, shoes learning and usage are quite simple. Listing 2 uses 70 lines of code to implement a calculator.
List 2. a calculator implemented by shoes
- class Calc
- def initialize
- @number = 0
- @previous = nil
- @op = nil
- end
-
- def to_s
- @number.to_s
- end
-
- (0..9).each do |n|
- define_method "press_#{n}" do
- @number = @number.to_i * 10 + n
- end
- end
-
- def press_clear
- @number = 0
- end
-
- {'add' => '+', 'sub' => '-', 'times' => '*', 'div' => '/'}.each do |meth, op|
- define_method "press_#{meth}" do
- if @op
- press_equals
- end
- @op = op
- @previous, @number = @number, nil
- end
- end
-
- def press_equals
- @number = @previous.send(@op, @number.to_i)
- @op = nil
- end
- end
-
- number_field = nil
- number = Calc.new
- Shoes.app :height => 250, :width => 200, :resizable => false do
- background "#EEC".."#996", :curve => 5, :margin => 2
-
- stack :margin => 2 do
-
- stack :margin => 8 do
- number_field = para strong(number)
- end
-
- flow :width => 218, :margin => 4 do
- %w(7 8 9 / 4 5 6 * 1 2 3 - 0 Clr = +).each do |btn|
- button btn, :width => 46, :height => 46 do
- method = case btn
- when /[0-9]/; 'press_'+btn
- when 'Clr'; 'press_clear'
- when '='; 'press_equals'
- when '+'; 'press_add'
- when '-'; 'press_sub'
- when '*'; 'press_times'
- when '/'; 'press_div'
- end
-
- number.send(method)
- number_field.replace strong(number)
- end
- end
- end
- end
- end
The introduction to Ruby and shoes is not covered in this article, but here are some of the most important structures:
Most ruby-class calc uses Ruby's meta-programming feature to define features for All numeric keys and mathematical operation keys at runtime.
Shoes. app... creates a GUI for the calculator to display the layout and buttons. Shoes provides two containers for assembly layout: Stack and flow. A stack is a vertical stack of elements, where each element is directly placed under the previous element. A flow wraps elements as closely as possible until it reaches its border limitations and then wraps the remaining elements. (You can think of a stack as an HTML <div> and a stream as an HTML <p> .) You can use a ruby block to create a stack or stream.
In the innermost flow, create all the buttons in the application and effectively bind each button to its method. (The case statement returns a method name; the number. Send (method) line calls the method on the instantiated calculator .)
The number_field.replace strong (number) Row uses the latest calculation result to update the calculator display. If the number is issued, the class calls its own to_s ("to string") method.
Other scripting languages have similar libraries and Ruby has more options, including Ruby cocoa. You can use Ruby to develop cocoa applications on Mac OS X. Select your preferred open source scripting language, find a lightweight GUI toolkit, and start coding.
You don't need a nasty compiler!
If you have mastered the shell script writing, combine your work with dialog or zenity to increase interoperability. If you need more programming functions than shell, consider a language like Ruby or Python and any Window Toolkit. You don't need a compiler to write a good desktop application.
About the author
Martin Streicher is a free Ruby on Rails developer and former editor of Linux magazine. Martin graduated from Purdue University and obtained a computer science degree. He has been engaged in programming UNIX systems since 1986. He likes to collect art and toys.