LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1327|回复: 2

(X)dialog: Talking shells

[复制链接]
发表于 2003-6-7 21:10:34 | 显示全部楼层 |阅读模式
(X)dialog: Talking shells

摘要:

Xdialog和dialog是两种能使你的shell脚本具备图形用户界面(GUI)的工具.
你需要具备一些shell编程知识才能看懂这篇文章. 你可以看我们的Shell Programming这篇文章来学一些shell编程的基础知识.



简介
即使没有图形用户界面, UNIX shell本身就是一个非常有效的工作环境.
但某些原因使得有一个图形的对话框会使用户觉得更加直观. 比如一个程序的安装对话框. 你有大量的选项用来选择安装的特征,你可以选择目标目录....
使用 (X)dialog...
使用dialog和Xdialog你仅需要写一句短短的shell脚本就可以实现一个图形的化应用程序. Dialog是一个完全依赖于终端的程序,  Xdialog则是一个X11程序.
这儿有一个例子:
你可以输入(或 拷备/粘贴)下面这些语句到一个shell窗口里(xterm,konsole,...):

bash
Xdialog --yesno "Do you want to learn more about Xdialog?" 0 0;\
case $? in
0)
echo "Result: Yes chosen.";;
1)
echo "Result: No chosen.";;
255)
echo "ESC pressed.";;
esac
运行结果看起像这样:


如果你用dialog代替Xdialog (把上面的脚本里第二行的 X 去掉), 你就可以看到一个运行在xterm里的基于curses的程序,而不是一个分离的窗口里(下图). 在某些情况下, 这样的运行方式更适合一个仅需要在一个终端窗口运行的脚本. 除非你想让它运行在多台无法与你直接路由的主机上. 这种情况下dialog可以顺利运行而Xdialog则不能.



上面这些dialog/Xdialog的例子漂亮但毫无用处, 但它们说明了编写一个图形化的对话框是容易的. 还有许多有趣的对话框, 包括如日历,菜单,文件管理器,进度条,文本输入,消息框,密码框,.....你可以试着运行:

dialog --help
或者
Xdialog --help
来得到一个可用的对话框列表. Xdialog 拥有的对话框类型要比dialog少.

它是如何工作的
这些对话框是通过命令行来给定参数的.

dialog --yesno "text string" <height> <width>
你输入dialog 或 Xdialog 后, 必须给定对话框的名字和你想设置的一引起特殊参数.

"yesno"对话框有3个参数. <height>和<width>可以设置为0, 对话框会根据文本的长度自动调整宽度和高度. 结果将把对话框结束状态返回给脚本并保存在"$?"变量中. 如果还有更多的值需要返回,如被选项的名字, 则这个值会被返回到标准错误中(standard error). 标准错误通常只是被打印到屏幕上,但可以用"2>"来进行重定向.

一个非常简单而有效的解决办法.

真正的程序
现在,让我们来看一个实用的程序,Xdialog/dialog将比传统的shell脚本程序提供更多的便利: 一个让可以选择不同的ISP(Internet Service Providers)并且进行连接的菜单. 这个脚本需要2001年5月的文章 Using different ISPs for your Internet access 里提供的ppp-on/ppp-off脚本. 我们这个脚本叫做 pppdialout, 它会根据你是否在线显示出不同的菜单.

#!/bin/sh
#
# pppdialout
#
#DIALOG=Xdialog
DIALOG=dialog
#
# 你的默认ISP的名字:
defaultisp=maxnet
#
error()
{
    echo "$1"
    exit 2
}
help()
{
  cat <<HELP
pppdialout -- select an ISP and dial out.
All available ISPs must have a config file in /etc/ppp/peers

pppdialout executes the ppp-on/ppp-off scripts as described
in http://linuxfocus.org/English/March2001/article192.shtml

pppdialout, copyright gpl, http://linuxfocus.org/English/November2002
HELP
  exit 0
}

# 分析命令行参数:
while [ -n "$1" ]; do
case $1 in
    -h) help;shift 1;; # function help is called
    --) shift;break;; # end of options
    -*) echo "error: no such option $1. -h for help";exit 1;;
    *)  break;;
esac
done

tempfile=/tmp/pppdialout.$$
trap "rm -f $tempfile" 1 2 5 15

# 检查是否已经连接internet
if /sbin/ifconfig | grep '^ppp' > /dev/null; then
    # 我们已经在线
    $DIALOG --title "go offline" --yesno "Click YES to \
                     terminate the ppp connection" 0 0
    rval="$?"
    clear
    if [ "$rval" = "0" ]; then
        echo "running /etc/ppp/scripts/ppp-off ..."
        /etc/ppp/scripts/ppp-off
    fi
else
    # 没发现internet连接, 进行连接
    # 从 /etc/ppp/peers 取得可用的ISP列表
    for f in `ls /etc/ppp/peers`; do
        if [ -f "/etc/ppp/peers/$f" ]; then
            isplist="$isplist $f =="
        fi
    done
    [ -z "$isplist" ]&&error "No isp def found in /etc/ppp/peers"
    #
    $DIALOG --default-item "$defaultisp" --title "pppdialout"  \
         --menu "lease select one of\
    the following ISPs for dialout" 0 0 0 $isplist 2> $tempfile
    rval="$?" # return status, isp name will be in $tempfile
    clear
    if [ "$rval" = "0" ]; then
        isp=`cat $tempfile`
        echo "running /etc/ppp/scripts/ppp-on $isp..."  
        /etc/ppp/scripts/ppp-on "$isp"
    else
        echo "Cancel..."   
    fi
    rm -f $tempfile
fi
# pppdialout 结束

这个脚本是如何工作的:
开始,我们定义了一些函数:error和help, 下一步我们检查命令行参数,然后定义了一相临时文件(/tmp/pppdialout.$$). $$是当前进行的名字,它在每一个计算机中都是独立的. 陷井语句在程序被强制中断(如用户按下Ctrl+C)是执行并且删除我们定义的临时文件. 然后我检查我们是否已经在线(命令:/sbin/ifconfig | grep '^ppp'). 如果我们已经在线则打开一个对话框, 就像上面你所看到的那样, 询问用户是否要断连接. 如果我们不在线就打开一个菜单对话框. 我们从 /etc/ppp/peers (ls /etc/ppp/peers)中取得所有可用的ISPs. 菜单对话框的语法是:

dialog --menu "text" <height> <width> <menu height> <tag1> <description> ...
<height>, <width> 和<menu height> 被设置为0(自动调整,请看上面),然后是程序预定的语法格式的字符串(<tag1> <description>). 我们没有什么描述,就用了一些无意义的东西(==). 变量ipslist中的数据看起来像这样:

isp1 == isp2 == isp3 ==
用户的选择结果会被打印到标准错误. 命令"2> $tmpfile" 把这一结果写到我们的临时文件(tmpfile)里. 这个菜单对话框有cancel可选, 所以我们必须检查 $? (退出状态) 以确定那一个键被按下.

好啦, 理论已经足够. 结果看起来是这样:

... Xdialog产生的漂亮的GTK图形界面:




... 终端里基于 curses 的 dialog :





更多的程序More applications
我们还有另一个程序要献给你. 它是一个叫做mktgz的使用Xdialog的checklist对话框的程序. 基于平面终端的dialog没有checklist对话框,所以它只能使用Xdialog了. 你可以用 mktgz来建立 tar.gz 的压缩包. 用法:

mktgz yourpackage .
这个程序会显示当前目录(".")下的所有文件, 然后你可以选择哪些文件需要加入到yourpackage.tar.gz 包中. 你可以在这里下载这个程序(mktgz.txt). 我们不算一句一句的解释这个脚本,因为你已经能够读懂这个脚本了.

Xdialog 和 dialog 自带的一些例子在一个叫"samples"的目录里(Redhat 7.3 里在 /usr/share/doc/Xdialog-2.0.5/samples下). 请注意这些脚本不仅仅是做演示, 它们会真的去做一些事情.


总结
Xdialog 和 dialog 提供了大量的对话框类型. 所有这些类型的对话框并不适合所有类型的脚本. shell 本身就是一个"强大"的环境. 用tab键来自动补全目录比在图形用户界面中点击它们要快很多. 特别是管道和组合命令更是一个强大的工具. 就像这样:

grep -i "somestring" file.txt | sort | uniq | wc -l

(UNIX的shells要做同样的事则没有这么容易: 计算file.txt里包含"somestring"字串的行的数目)
可以用这种管道结构是因为这些命令全由命令行参数来控制. 换句话说: 它们不会停下来问用户它将如何继续运行.
虽然在程序中图形对话框非常有用, Xdialog 和 dialog 非常易于使用, 但必尽没有真正的图形化程序强大. 它们填补一纯ASCII shell脚本和全图形化程序这间的缺口.  
在那里下载 Xdialog 和 dialog?
首先可以找的地方是你的linux发行版光盘里. 也许已经安装到了你的计算机里(查询你的计算机: 如 rpm -qil Xdialog, dpkg -L Xdialog). Xdialog的主页是:
http://www.chez.com/godefroy/
dialog的主页是:
http://hightek.org/dialog/
发表于 2003-6-7 22:28:35 | 显示全部楼层
很好的文章!
发表于 2003-6-8 19:04:53 | 显示全部楼层
GOOD,I WILL TRY IT
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表