Shell编程—图形化脚本
1创建文本菜单
1.1普通的文本菜单
$ cat menu1 #!/bin/bash # simple script menu function diskspace { clear df -k } function whoseon { clear who } function memusage { clear cat /proc/meminfo } function memu{ clear echo 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" echo -en "\t\tEnter option: " read -n 1 option } while [ 1 ] do menu case $option in 0) break ;; 1) diskspace ;; 2) whoseon ;; 3) memusage ;; *) clear echo "Sorry, wrong selection";; esac echo -en "\n\n\t\t\tHit any key to continue" read -n 1 line done clear
1.2 使用select命令创建
select命令只需要一条命令就可以创建出菜单,然后获取输入的答案并自动处理。select命令格式如下:
select variable in list do commands done
list参数是由空格分隔的文本选项列表,这些列表构成了整个菜单。select命令会将每个列表项显示成一个带编号的选项,然后为选项显示一个由PS3环境变量定义的特殊提示符。
$ cat smenu1 #!/bin/bash # using select in the menu function diskspace { clear df -k } function whoseon { clear who } function memusage { 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") memusage ;; *) clear echo "Sorry, wrong selection";; esac done clear
select语句中的所有内容必须作为一行出现。这可以从行接续字符中看出。运行这个程序时,它会自动生成如下菜单:
$ ./smenu1 1) Display disk space 3) Display memory usage 2) Display logged on users 4) Exit program Enter option:
2制作窗口
2.1dialog 包
dialog命令使用命令行参数来决定生成哪种窗口部件(widget)。部件是dialog包中窗口元素类型的术语。dialog包现在支持的部件类型:
部 件 |
描 述 |
calendar |
提供选择日期的日历 |
checklist |
显示多个选项(其中每个选项都能打开或关闭) |
form |
构建一个带有标签以及文本字段(可以填写内容)的表单 |
fselect |
提供一个文件选择窗口来浏览选择文件 |
gauge |
显示完成的百分比进度条 |
infobox |
显示一条消息,但不用等待回应 |
inputbox |
提供一个输入文本用的文本表单 |
inputmenu |
提供一个可编辑的菜单 |
menu |
显示可选择的一系列选项 |
msgbox |
显示一条消息,并要求用户选择OK按钮 |
pause |
显示一个进度条来显示暂定期间的状态 |
passwordbox |
显示一个文本框,但会隐藏输入的文本 |
passwordform |
显示一个带标签和隐藏文本字段的表单 |
radiolist |
提供一组菜单选项,但只能选择其中一个 |
tailbox |
用tail命令在滚动窗口中显示文件的内容 |
tailboxbg |
跟tailbox一样,但是在后台模式中运行 |
textbox |
在滚动窗口中显示文件的内容 |
timebox |
提供一个选择小时、分钟和秒数的窗口 |
yesno |
提供一条带有Yes和No按钮的简单消息 |
要在命令行上指定某个特定的部件,需使用双破折线格式。
dialog --widget parameters
其中widget是表18-1中的部件名,parameters定义了部件窗口的大小以及部件需要的文本。
每个dialog部件都提供了两种形式的输出:
- 使用退出状态码
- 使用STDERR
可以通过dialog命令的退出状态码来确定用户选择的按钮。如果选择了Yes或OK按钮, dialog命令会返回退出状态码0。如果选择了Cancel或No按钮, dialog命令会返回退出状态码1。
可以用标准的$?变量来确定dialog部件中具体选择了哪个按钮。
如果部件返回了数据,比如菜单选择,那么dialog命令会将数据发送到STDERR。可以用标准的bash shell方法来将STDERR输出重定向到另一个文件或文件描述符中:
dialog --inputbox "Enter your age:" 10 20 2>age.txt
1. msgbox部件
dialog --msgbox text height width
text参数是你想在窗口中显示的字符串。dialog命令会根据由height和width参数创建的窗口的大小来自动换行。如果想在窗口顶部放一个标题,也可以用--title参数,后接作为标题的文本。这里有个使用msgbox部件的例子:
$ dialog --title Testing --msgbox "This is a test" 10 20
在输入这条命令后,消息框会显示在你所用的终端仿真器会话的屏幕上:
2. yesno部件
这里有个使用yesno部件的例子。
$ dialog --title "Please answer" --yesno "Is this thing on?" 10 20 $ echo $? 1
3. inputbox部件
$ dialog --inputbox "Enter your age:" 10 20 2>age.txt $ echo $? 0 $ cat age.txt 12
4.textbox部件
$ dialog --textbox /etc/passwd 15 45
/etc/passwd文件的内容会显示在可滚动的文本窗口中:
5. menu部件
$ dialog --menu "Sys Admin Menu" 20 30 10 1 "Display disk space" 2 "Display users" 3 "Display memory usage" 4 "Exit" 2> test.txt
menu部件允许你来创建我们之前所制作的文本菜单的窗口版本。第一个参数定义了菜单的标题,之后的两个参数定义了菜单窗口的高和宽,而第四个参数则定义了在窗口中一次显示的菜单项总数。如果有更多的选项,可以用方向键来滚动显示它们。
6. fselect部件
$ dialog --title "Select a file" --fselect $HOME/ 10 50 2>file.txt
可以用fselect部件来浏览文件的位置并选择文件:
fselect选项后的第一个参数是窗口中使用的起始目录位置。fselect部件窗口由左侧的目录列表、右侧的文件列表(显示了选定目录下的所有文件)和含有当前选定的文件或目录的简单文本框组成。可以手动在文本框键入文件名,或者用目录和文件列表来选定(使用空格键选择文件,将其加入文本框中)。
2.2dialog 选项
除了标准部件,还可以在dialog命令中定制很多不同的选项:
选 项 |
描 述 |
--add-widget |
继续下个对话框,直到按下Esc或Cancel按钮 |
--aspect ratio |
指定窗口宽度和高度的宽高比 |
--backtitle title |
指定显示在屏幕顶部背景上的标题 |
--begin x y |
指定窗口左上角的起始位置 |
--cancel-label label |
指定Cancel按钮的替代标签 |
--clear |
用默认的对话背景色来清空屏幕内容 |
--colors |
在对话文本中嵌入ANSI色彩编码 |
--cr-wrap |
在对话文本中允许使用换行符并强制换行 |
--create-rc file |
将示例配置文件的内容复制到指定的file文件中① |
--defaultno |
将yes/no对话框的默认答案设为No |
--default-item string |
设定复选列表、表单或菜单对话中的默认项 |
--exit-label label |
指定Exit按钮的替代标签 |
--extra-button |
在OK按钮和Cancel按钮之间显示一个额外按钮 |
--extra-label label |
指定额外按钮的替代标签 |
--help |
显示dialog命令的帮助信息 |
--help-button |
在OK按钮和Cancel按钮后显示一个Help按钮 |
--help-label label |
指定Help按钮的替代标签 |
--help-status |
当选定Help按钮后,在帮助信息后写入多选列表、单选列表或表单信息 |
--ignore |
忽略dialog不能识别的选项 |
--input-fd fd |
指定STDIN之外的另一个文件描述符 |
--insecure |
在password部件中键入内容时显示星号 |
--item-help |
为多选列表、单选列表或菜单中的每个标号在屏幕的底部添加一个帮助栏 |
--keep-window |
不要清除屏幕上显示过的部件 |
--max-input size |
指定输入的 大字符串长度。默认为2048 |
--nocancel |
隐藏Cancel按钮 |
--no-collapse |
不要将对话文本中的制表符转换成空格 |
--no-kill |
将tailboxbg对话放到后台,并禁止该进程的SIGHUP信号 |
--no-label label |
为No按钮指定替代标签 |
--no-shadow |
不要显示对话窗口的阴影效果 |
--ok-label label |
指定OK按钮的替代标签 |
--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秒后退出并返回错误代码 |
--title title |
指定对话窗口的标题 |
--trim |
从对话文本中删除前导空格和换行符 |
--visit-items |
修改对话窗口中制表符的停留位置,使其包括选项列表 |
--yes-label label |
为Yes按钮指定替代标签 |
--backtitle选项是为脚本中的菜单创建公共标题的简便办法。如果你为每个对话窗口都指 定了该选项,那么它在你的应用中就会保持一致。
2.3在脚本中使用dialog命令
$ cat menu3 #!/bin/bash # using dialog to create a menu 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 memusage { 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 users" 3 "Display memory usage" 0 "Exit" 2> $temp2 if [ $? -eq 1 ] then break fi selection=$(cat $temp2) case $selection in 1) diskspace ;; 2) whoseon ;; 3) memusage ;; 0) break ;; *) dialog --msgbox "Sorry, invalid selection" 10 30 esac done rm -f $temp 2> /dev/null rm -f $temp2 2> /dev/null
这段脚本用while循环和一个真值常量创建了个无限循环来显示菜单对话。这意味着,执行完每个函数之后,脚本都会返回继续显示菜单。
由于menu对话包含了一个Cancel按钮,脚本会检查dialog命令的退出状态码,以防用户按下Cancel按钮退出。因为它是在while循环中,所以退出该菜单就跟用break命令跳出while循环一样简单。
脚本用mktemp命令创建两个临时文件来保存dialog命令的数据。第一个临时文件$temp用来保存dfmeminfo命令的输出,这样就能在textbox对话中显示它们了
3使用图形
kdialog和zenity包:各自为KDE和GNOME桌面提供了图形化窗口部件。
3.1KDE 环境
KDE图形化环境默认包含kdialog包。kdialog命令的格式:
kdialog display-options window-options arguments
1 . kdialog部件
window-options选项允许指定使用哪种类型的窗口部件:
选 项 |
描 述 |
--checklist title [tag item status] |
带有状态的多选列表菜单,可以表明选项是否被选定 |
--inputbox text [init] |
输入文本框。可以用init值来指定默认值 |
--menu title [tag item] |
带有标题的菜单选择框,以及用tag标识的选项列表 |
--msgbox text |
显示指定文本的简单消息框 |
--password text |
隐藏用户输入的密码输入文本框 |
--radiolist title [tag item status] |
带有状态的单选列表菜单,可以表明选项是否被选定 |
--separate-output |
为多选列表和单选列表菜单返回按行分开的选项 |
--sorry text |
“对不起”消息框 |
--textbox file [width] [height] |
显示file的内容的文本框,可以指定width和height |
--title title |
为对话窗口的TitleBar区域指定一个标题 |
--warningyesno text |
带有Yes和No按钮的警告消息框 |
--warningcontinuecancel text |
带有Continue和Cancel按钮的警告消息框 |
--warningyesnocancel text |
带有Yes、No和Cancel按钮的警告消息框 |
--yesno text |
带有Yes和No按钮的提问框 |
--yesnocancel text |
带有Yes、No和Cancel按钮的提问框 |
checklist和radiolist部件允许你在列表中定义单独的选项以及它们默认是否选定。
$kdialog --checklist "Items I need" 1 "Toothbrush" on 2 "Toothpaste" off 3 "Hair brush" on 4 "Deodorant" off 5 "Slippers" off
最终的多选列表窗口:
指定为on的选项会在多选列表中高亮显示。要选择或取消选择多选列表中的某个选项,只要单击它就行了。如果选择了OK按钮,kdialog就会将标号值发到STDOUT上。
"1" "3" $
当按下回车键时,kdialog窗口就和选定选项一起出现了。当单击OK或Cancel按钮时, kdialog命令会将每个标号作为一个字符串值返回到STDOUT(这些就是你在输出中看到的"1" 和"3")。脚本必须能解析结果值并将它们和原始值匹配起来。
2. 使用kdialog
$ cat menu4 #!/bin/bash # using kdialog to create a menu temp=$(mktemp -t temp.XXXXXX) temp2=$(mktemp -t temp2.XXXXXX) function diskspace { df -k > $temp kdialog --textbox $temp 1000 10 } function whoseon { who > $temp kdialog --textbox $temp 500 10 } function memusage { cat /proc/meminfo > $temp kdialog --textbox $temp 300 500 } while [ 1 ] do kdialog --menu "Sys Admin Menu" "1" "Display diskspace" "2" "Display users" "3" "Display memory usage" "0" "Exit" > $temp2 if [ $? -eq 1 ] then break fi selection=$(cat $temp2) case $selection in 1) diskspace ;; 2) whoseon ;; 3) memusage ;; 0) break ;; *) kdialog --msgbox "Sorry, invalid selection" esac done $ cat menu4 #!/bin/bash # using kdialog to create a menu temp=$(mktemp -t temp.XXXXXX) temp2=$(mktemp -t temp2.XXXXXX) function diskspace { df -k > $temp kdialog --textbox $temp 1000 10 } function whoseon { who > $temp kdialog --textbox $temp 500 10 } function memusage { cat /proc/meminfo > $temp kdialog --textbox $temp 300 500 } while [ 1 ] do kdialog --menu "Sys Admin Menu" "1" "Display diskspace" "2" "Display users" "3" "Display memory usage" "0" "Exit" > $temp2 if [ $? -eq 1 ] then break fi selection=$(cat $temp2) case $selection in 1) diskspace ;; 2) whoseon ;; 3) memusage ;; 0)
3.2GNOME 环境
GNOME图形化环境支持两种流行的可生成标准窗口的包:
- gdialog
- zenity
1. zenity部件
选 项 |
描 述 |
--calendar |
显示一整月日历 |
--entry |
显示文本输入对话窗口 |
--error |
显示错误消息对话窗口 |
--file-selection |
显示完整的路径名和文件名对话窗口 |
--info |
显示信息对话窗口 |
--list |
显示多选列表或单选列表对话窗口 |
--notification |
显示通知图标 |
--progress |
显示进度条对话窗口 |
--question |
显示yes/no对话窗口 |
--scale |
显示可调整大小的窗口 |
--text-info |
显示含有文本的文本框 |
--warning |
显示警告对话窗口 |
zenity命令行程序与kdialog和dialog程序的工作方式有些不同。许多部件类型都用另外的命令行选项定义,而不是作为某个选项的参数。
zenity命令能够提供一些非常酷的高级对话窗口。calendar选项会产生一个整月的日历,如图:
当在日历中选择了日期时,zenity命令会将值返回到STDOUT中,就和kdialog一样。
$ zenity --calendar 12/25/2011 $
zenity中另一个很酷的窗口是文件选择选项,如图:
可以用对话窗口来浏览系统上任意一个目录位置(只要你有查看该目录的权限),并选择文件。当你选定文件时,zenity命令会返回完整的文件路径名。
$ zenity --file-selection
/home/ubuntu/menu5
$
2. 在脚本中使用zenity
$cat menu5 #!/bin/bash # using zenity to create a menu temp=$(mktemp -t temp.XXXXXX) temp2=$(mktemp -t temp2.XXXXXX) function diskspace { df -k > $temp zenity --text-info --title "Disk space" --filename=$temp --width 750 --height 10 } function whoseon { who > $temp zenity --text-info --title "Logged in users" --filename=$temp --width 500 --height 10 } function memusage { cat /proc/meminfo > $temp zenity --text-info --title "Memory usage" --filename=$temp --width 300 --height 500 } while [ 1 ] do zenity --list --radiolist --title "Sys Admin Menu" --column "Select" --column "Menu Item" FALSE "Display diskspace" FALSE "Display users" FALSE "Display memory usage" FALSE "Exit" > $temp2 if [ $? -eq 1 ] then break fi selection=$(cat $temp2) case $selection in "Display disk space") diskspace ;; "Display users") whoseon ;; "Display memory usage") memusage ;; Exit) break ;; *) zenity --info "Sorry, invalid selection" esac done