摘要:本章主要讲如何增加脚本的交互性功能。

read - 从标准输入读取数值

read 内部命令被用来从标准输入读取单行数据。这个命令可以用来读取键盘输入,当使用重定向的时候,读取文件中的一行数据。这个命令有以下语法形式:

read [-options] [variable...]

options 是下面列出的可用选项中的一个或多个,且 variable 是用来存储输入数值的一个或多个变量名。

如果 read 命令接受到变量值数目少于期望的数字,那么额外的变量值为空,而多余的输入数据则会被包含到最后一个变量中。

选项

read 支持以下选项:

选项 说明
-a array 把输入赋值到数组 array 中,从索引号零开始。
-d delimiter 用字符串 delimiter 中的第一个字符指示输入结束,而不是一个换行符。
-e 使用 Readline 来处理输入。这使得与命令行相同的方式编辑输入。
-n num 读取 num 个输入字符,而不是整行。
-p prompt 为输入显示提示信息,使用字符串 prompt。
-r Raw mode. 不把反斜杠字符解释为转义字符。
-s Silent mode. 不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这会很有帮助。
-t seconds 超时. 几秒钟后终止输入。若输入超时,read 会返回一个非零退出状态。
-u fd 使用文件描述符 fd 中的输入,而不是标准输入。

IFS

通常,shell 对提供给 read 的输入按照单词进行分离。正如我们所见到的,这意味着多个由一个或几个空格分离开的单词在输入行中变成独立的个体,并被 read 赋值给单独的变量。这种行为由 shell 变量 IFS (内部字符分隔符)配置。IFS 的默认值包含一个空格,一个 tab,和一个换行符,每一个都会把字段分割开。

我们可以调整 IFS 的值来控制输入字段的分离。例如,这个 /etc/passwd 文件包含的数据行使用冒号作为字段分隔符。通过把 IFS 的值更改为单个冒号,我们可以使用 read 读取 /etc/passwd 中的内容,并成功地把字段分给不同的变量。

不能把管道用在 read 上

答案与 shell 处理管道线的方式有关系。在 bash(和其它 shells,例如 sh)中,管道线会创建子 shell。这个子 shell 是为了执行执行管线中的命令而创建的 shell 和它的环境的副本。

在类 Unix 的系统中,子 shell 执行的时候,会为进程创建父环境的副本。当进程结束之后,该副本就会被破坏掉。这意味着一个子 shell 永远不能改变父进程的环境。

菜单

一种常见的交互类型称为菜单驱动。在菜单驱动程序中,呈现给用户一系列选择,并要求用户选择一项。

总结归纳

在这一章中,我们向着程序交互性迈出了第一步;允许用户通过键盘向程序输入数据。使用目前已经学过的技巧,有可能编写许多有用的程序,比如说特定的计算程序和容易使用的命令行工具前端。在下一章中,我们将继续建立菜单驱动程序概念,让它更完善。