前面曾经提到,在Linux中使用的bash(不管是图形模式里的terminal还是文本模式里的console)是交互式的.用户在bash提示符后输入一个命令, bash执行后将信息反馈给用户.
所谓的非交互式bash一般是针对脚本而言的, 我们可以把脚本写成非交互式的: 不需要读取用户的输入, 也不用向用户反馈某些信息. 非交互式有两个特点: (1)每次执行都是可预见的, 因为它不读取用户输入, 参数是固定的. (2) 可以在后台执行.
与非交互式脚本对应的是交互式脚本: 它可以读取用户的输入, 实时向用户反馈信息. 这样的脚本更灵活, 每次执行时的参数可由用户动态设定. 用户界面也更友好.
实际上, "交互"的含义就是脚本能向用户输出某些信息或读取用户的输入.
1, 输出信息
一般使用echo, printf这样的bash内嵌命令来输出信息.
echo
echo向stdout输出表达式或变量. 默认地, echo会在输出后换行. 可以有两种方式关闭echo的换行:
$
echo -n "hello, world"
$
echo -e "hello, world\c"
-n去掉echo末尾的换行符, -e打印出转义字符. 在linux/bash系统中, 推荐使用-n.
printf
如果想生成格式化输出, 建议使用printf而非echo. 老版本的bash不支持printf, 但教新的都支持.
printf和c中的printf函数很像:
printf “format string” parameter1 parameter2 ...
但bash中的printf不能输出浮点数(bash中的算术运算都是针对整数执行的).
$
printf "%s %d\t %s\n" "hi there" 15 "people"
hi there 15 people
2, 读取用户输入
与echo或printf相对, bash使用echo来读取用户输入, read的格式如下:
read [options] NAME1 NAME2 ... NAMEN
注意: 用户输入值由IFS分隔, 它们被以此赋给NAME1, NAME2...NAMEN. 如果用户的输入少于n个,
那么多余的NAMEM~NAMEN的值为空. 如果未指定NAME1~NAMEN, 那么用户输入被赋给REPLY变量.
read还可以使用-u选项来读取文件描述符.
若read读取成功, 那么返回值为0. read出错的情况可能有: 读取EOF文件结束符, 指定的文件描述符无效.
e.g.
$
echo "input your name"
$
read NAME
or $
read
$
echo $NAME or $
echo $REPLY
read的选项列于下表:
| Option | Meaning |
|---|
| -a ANAME | The words are assigned to sequential indexes of the array variable ANAME, starting at 0. All elements are removed from ANAME before the assignment. Other NAME arguments are ignored. |
| -d DELIM | The first character of DELIM is used to terminate the input line, rather than newline. |
| -e | readline is used to obtain the line. |
| -n NCHARS | read returns after reading NCHARS characters rather than waiting for a complete line of input. |
| -p PROMPT | Display PROMPT,
without a trailing newline, before attempting to read any input. The
prompt is displayed only if input is coming from a terminal. |
| -r | If
this option is given, backslash does not act as an escape character.
The backslash is considered to be part of the line. In particular, a
backslash-newline pair may not be used as a line continuation. |
| -s | Silent mode. If input is coming from a terminal, characters are not echoed. |
| -t TIMEOUT | Cause read to time out and return failure if a complete line of input is not read within TIMEOUT seconds. This option has no effect if read is not reading input from the terminal or from a pipe. |
| -u FD | Read input from file descriptor FD. |
3, 读入及输出文件
使用图形前端显示交互式脚本的运行
可以使用dialog或Xdialog来构建脚本的前端界面. dialog是基于控制台的, 我们熟悉的Linux的menuconfig界面就是使用的dialog. Xdialog是基于x11的, 显示更加友好.
Ubuntu/Debian上默认是没有安装dialog和Xdialog的, 下面的命令安装它们:
$
sudo apt-get install dialog xdialog
OK, 下面看看dialog和Xdialog的用法.
(一) 一个简单的示例.
#!/bin/bash
DIALOG=${DIALOG=dialog}
$DIALOG --title " My first dialog" --clear \
--yesno "Hello , this is my first dialog program" 10 30
运行它, 得到下面的图形:
将DIALOG=${DIALOG=dialog}改为DIALOG=${DIALOG=Xdialog}, 再次执行上述的脚本
下面解释一下上述的脚本:
#!/bin/bash就不用多说了, 所有的bash脚本起始行都是它.
DIALOG=${DIALOG=dialog} 设置DIALOG变量, 你可以将它设置为dialog或Xdialog(注意X为大写!)
重点是dialog的选项, 选项以"--"为前缀, 后面跟着可选的参数.
--title : 窗口的名称.
--clear : 在显示窗口之前清屏.
--yesno : 指定窗口的模板. dialog支持多种窗口, 见下表:
| 选 项 |
窗口类型
|
| --yesnobox |
含有"yes"和"no"按钮 |
| --menu |
构建菜单 |
| --inputbox |
读取用户输入 |
| --msgbox |
只含有"ok"按钮 |
| --textbox |
在dialog中显示文本文文件的内容 |
| --infobox |
与--msgbox相似
|
| --checklist |
与--menu相似, 但可显示那些条目被选择了. |
| --radiolist |
与--menu相似, 但可显示那些条目被选择了.
|
关于dialog, Xdialog的更多信息
http://linuxgazette.net/101/sunil.html
http://www2.linuxjournal.com/article/2807
Dialog脚本示例:
http://www.fifi.org/doc/dialog/examples/.