----------------------------本文地址:http://blog.51cto.com/woonli/2142606
----------------------------参考网址http://linuxcommand.org/lc3_adv_dialog.php

一、简介
dialog是Linux图形化自动脚本编程的工具,实现脚本中图形化,它是一个相当大而复杂的程序(它有近100个命令行选项),但与典型的图形用户界面相比,它是一个真正的轻量级。尽管如此,它仍然具有许多用户界面技巧;
二、使用条件
dialog在多数Linux发行版上已经默认安装如果没有安装,
rpm系列用以下的其中一个:
a、 yum install dialog -y
b、 rpm -vih dialog
deb系统用以下中的一个:
a、sudo apt-get install dialog
b、sudo dpkg -i dialog
三、dianlog帮助信息
dialog有很多命令选项,记忆困难,但如果理解了它,加上帮助信息,你会马上拥有她;dialog的帮助很简单,在终端中输入dialog命令即可;帮助信息如下:

cdialog (ComeOn Dialog!) version 1.3-20160828
Copyright 2000-2015,2016 Thomas E. Dickey
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

* Display dialog boxes from shell scripts *

Usage: dialog <options> { --and-widget <options> }
where options are "common" options, followed by "box" options

Special options:
  [--create-rc "file"]
Common options:
  [--ascii-lines] [--aspect <ratio>] [--backtitle <backtitle>] [--beep]
  [--beep-after] [--begin <y> <x>] [--cancel-label <str>] [--clear]
  [--colors] [--column-separator <str>] [--cr-wrap] [--date-format <str>]
  [--default-button <str>] [--default-item <str>] [--defaultno]
  [--exit-label <str>] [--extra-button] [--extra-label <str>]
  [--help-button] [--help-label <str>] [--help-status] [--help-tags]
  [--hfile <str>] [--hline <str>] [--ignore] [--input-fd <fd>]
  [--insecure] [--item-help] [--keep-tite] [--keep-window] [--last-key]
  [--max-input <n>] [--no-cancel] [--no-collapse] [--no-cr-wrap]
  [--no-items] [--no-kill] [--no-label <str>] [--no-lines] [--no-mouse]
  [--no-nl-expand] [--no-ok] [--no-shadow] [--no-tags] [--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]
  [--week-start <str>] [--yes-label <str>]
Box options:
  --buildlist    <text> <height> <width> <list-height> <tag1> <item1> <status1>...
  --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>
  --prgbox       <text> <command> <height> <width>
  --programbox   <text> <height> <width>
  --progressbox  <text> <height> <width>
  --radiolist    <text> <height> <width> <list height> <tag1> <item1> <status1>...
  --rangebox     <text> <height> <width> <min-value> <max-value> <default-value>
  --tailbox      <file> <height> <width>
  --tailboxbg    <file> <height> <width>
  --textbox      <file> <height> <width>
  --timebox      <text> <height> <width> <hour> <minute> <second>
  --treeview     <text> <height> <width> <list-height> <tag1> <item1> <status1> <depth1>...
  --yesno        <text> <height> <width>

Auto-size with height and width = 0. Maximize with height and width = -1.
Global-auto-size if also menu_height/list_height = 0.

四、帮助信息解析

Usage: dialog <options> { --and-widget <options> }

dialog 命令后是common options,即通用选项,是图形化框的一些个性化配置信息,依据是否需要可以省略;而--and-widget 是各类图形化部件,后边重点介绍,部件的options主要是针对部件的高、宽、内容、位置等参数的设置;
如帮助信息中的

  --buildlist    <text> <height> <width> <list-height> <tag1> <item1> <status1>...

是为了构建并排显示两个列表。左侧的列表包含未选择的项目,右侧所选项目的列表。用户可以将项目从一个列表移动到另一个列表。
在--buildlist的options中,

<text> <height> <width> <list-height> <tag1> <item1> <status1>...

"<text>"是自定义框体名称,<height> <width>是框体的高和宽,默认值为0,默认时自适应大小,<list-height>是列表选择框的高度,<tag1> 是列表选择框的提示或者标题等;<item1>是列表的选项; <status1>“可能是选择该条目的状态,这个暂时也不清楚”
具体的命令如下:

dialog --title "列表框" --buildlist "选择" 0 0 15 "USER" "CPU" 0 "MEM" "MEM" 1

具体效果如下
Linux图形化编程dialog
OK~,其他选项框也是类似的帮助信息;下面介绍部门options选项

  1. common options
    [--no-shadow] 禁止阴影出现在每个对话框的底部
    [--shadow] 应该是出现阴影效果[--insecure] 输入部件的密码时,明文显示不安全,使用星号来代表每个字符[--no-cancel] 设置在输入框,菜单,和复选框中,不显示“cancel”项
    [--clear] 完成清屏操作。在框体显示结束后,清除框体。这个参数只能单独使用,不能和别的参数联合使用。
    [--ok-label <str>] 覆盖使用“OK”按钮的标签,换做其他字符。
    [--cancel-label <str>] 功能同上
    [--backtitle <backtitle>] 指定的backtitle字符串显示在背景顶端。
    [--begin <y> <x>] 指定对话框左上角在屏幕的上的做坐标
    [--timeout <secs>] 超时(返回的错误代码),如果用户在指定的时间内没有给出相应动作,就按超时处理
    [--defaultno] 使的是默认值 yes/no,使用no
    [--sleep <secs>]
    [--stderr] 以标准错误方式输出
    [--stdout] 以标准方式输出
    [--default-item <str>] 设置在一份清单,表格或菜单中的默认项目。通常在框中的第一项是默认。
  2. Windows options
对话 选项 描述
构建列表 --buildlist 并排显示两个列表。左侧的列表包含未选择的项目,右侧所选项目的列表。用户可以将项目从一个列表移动到另一个列表。
日历 --calendar 显示日历并允许用户选择日期。
清单 --checklist 显示选项列表,并允许用户选择一个或多个项目。
目录选择 --dselect 显示目录选择对话框。
编辑框 --editbox 显示基本文本文件编辑器。
形成 --form 允许用户在多个字段中输入文本。
文件选择 --fselect 文件选择对话框。
测量 --gauge 显示进度指示器,显示完成百分比。
信息框 --infobox 显示消息(带有可选的定时暂停)并终止。
输入框 --inputbox 提示用户输入/编辑文本字段。
菜单框 --menubox 显示选项列表。
消息框 --msgbox 显示文本消息并等待用户响应。
密码箱 --passwordbox 与输入框类似,但隐藏用户的条目。
暂停 --pause 显示文本消息和倒数计时器。当计时器用完或用户按下“确定”或“取消”按钮时,对话框将终止。
程序框 --programbox 显示管道命令的输出。命令完成后,对话框将等待用户按下OK按钮。
进度框 --progressbox 类似于程序框,除了对话框在管道命令完成时终止,而不是等待用户按OK。
电台名单 --radiolist 显示选项列表,并允许用户选择单个项目。之前选择的任何项目都将被取消选中。
范围框 --rangebox 允许用户使用基于键盘的滑块在指定范围内选择数值。
尾箱 --tailbox 显示具有实时更新的文本文件。像命令一样工作tail -f。
文本框 --textbox 简单的文本文件查看器。支持许多相同的键盘命令less。
时间盒 --timebox 用于输入时间的对话框。
树视图 --treeview 显示树形层次结构中的项目列表。
是/否盒子 --yesno 显示文字信息,让用户有机会回答“是”或“否”。

五、在shell脚本中使用
dialog图形化主要是在运维过程中图形自动化脚本人机交互时使用,图形化的选择或提示等,可操作行更强。
dialog在脚本中使用需要主要以下两点:
a、dialog在绘制会话框本身时使用标准输出作为终端显示,所以在会话框上的输入(例如输入到输入框中的字符串)通常通过标准错误返回,这就导致了dialog获取数据的问题,要解决该问题,需要将错误输出转换为标准输出文件提示符;解决该问题的方法有两种:
1)、使用临时存储文件
2)使用文件描述符
b、dialog图形化中的状态码,在使用dialog前先了解状态码;如“OK”为0,“NO”为1,"ESC"为255,还可以定义其他状态码,如帮助信息等等。

六、脚本实例
本脚本实例中为解决错误输出转换问题使用文件描述符,基本上多数dialog脚本中都使用文件描述符;格式为
exec 3>&1
dialog --widdget options 2>&1 1>&3
exec 3>&1;
该命令包括将描述符2(stderr)重定向为描述符1的副本,最后,通过复制包含备份副本的描述符3,将描述符1恢复为其原始值。可能不会立即显示的是为什么需要最后一次重定向。在子shell中,标准输出(描述符1)不指向控制终端。相反,它指向一个将其内容传递给变量的管道result。由于dialog需要标准输出指向终端以便它可以显示输入框,我们必须将标准错误重定向到标准输出(以便输出dialog结束于result 变量),然后将标准输出重定向回控制终端。
脚本实例:

#!/bin/bash
#Dialog use case
#Author by woon

## Define the dialog exit status codes
#可以不定义退出码。直接使用值也行。
: ${DIALOG_OK=0}
: ${DIALOG_CANCEL=1}
: ${DIALOG_HELP=2}
: ${DIALOG_EXTRA=3}
: ${DIALOG_ITEM_HELP=4}
: ${DIALOG_ESC=255}

#定义msgbox函数
display_box() {
dialog --title "$1" \
    --no-collapse \
    --msgbox "$res" 0 0
    }
while true;do
    #将标准输出复制一份到文件描述符3,  
    exec 3>&1
    selection=$(dialog --title "系统监测" \
        --clear \
        --ok-label "Submit" \
        --cancel-label "Exit" \
        --menu "选择监测项:" 0 0 10 \
        "1" "当前用户占用资源情况" \
        "2" "当前磁盘使用情况" \
        "3" "CPU相关信息" \
        "4" "MEM相关信息" \
        2>&1 1>&3   #将错误输出转换为标准输出
        )

    exit_status=$?
    exec 3>&- #关闭文件描述符3
    case $exit_status in 
        $DIALOG_CANCEL)
        clear
        echo "程序终止"
        exit
        ;;
    $DIALOG_ESC)
    clear 
    echo "程序终止"
    exit 1
    ;;
esac
case $selection in 
    0)
        clear
        echo "程序终止"
        ;;
    1)
        pcpu=$(ps -eo user,pcpu,pmem | awk -v user=$USER '$1==user{print $0}'|awk '{pcpu+=$2}END{print pcpu}')
        pmem=$(ps -eo user,pcpu,pmem | awk -v user=$USER '$1==user{print $0}'|awk '{pcpu+=$2}END{print pcpu}')
        res="当前用户占用CPU:"$pcpu"\n当前用户占用内存:"$pmem
        display_box "当前用户占用资源情况"
        ;;
    2)
        res=$(df -h)
        display_box "当前磁盘使用情况"
        ;;
    3)
        res=$(dmesg | grep CPU | awk -F "] " '{print $2}')
        display_box "CPU硬件信息"
        ;;
    4)
        res=$(head -10 /proc/meminfo )
        display_box "系统内存信息"
        ;;
esac
done