目录
摘要
本章我们将讨论怎么通过脚本来和合用户交流:
打印用户友好的消息和解释
捕捉用户的输入
提示用户输入
使用文件描述符来读取和写入到多个文件
一些脚本根本不需要来自用户的交互信息。非交互脚本的优势包括:
脚本每次都以可以预测行为运行。
脚本可以在后台运行。
然而许多脚本,需要来自用户的输入,或者在运行的时候给用户输出信息。交互脚本的优势在于:
可以建立更加灵活的脚本。
用户可自定义脚本使得其在运行时产生不同的行为。
脚本可以在运行过程中报告状态。
当编写交互脚本的时候,不要省略注释。打印适当的信息的脚本能变的更加友好且更加容易调试。一个脚本可能做一件完美的工作,但是如果脚本不通知用户正在进行的工作,你将会得到许多来自用户的帮助请求。所以请把告诉用户等待计算完成的输出的提示信息包含进脚本。如果可能的话,尝试提醒下用户需要等待多长的时间。如果再执行某个特定任务的时候等待通常要持续很长时间,你可能会考虑把一些关于脚本输出进度的指示一起集成到脚本当中去。
当提示用户进行输入的时候,同样对输入数据的类型最好给出更多的相关信息。同样在检查参数的时候也采取同样的使用方法信息。
Bash有 echo 和 printf 命令提供注释给用户,尽管你现在应该已经熟悉了 echo 的使用方法,但是我们在以下还是会讨论更多的例子。
内建命令 echo 输出他的参数,以空格来分隔,以换行符来结束。返回值总为0。 echo 使用的一些选项:
-e
:解释反斜杠转义字符。
-n
:禁止换行。
作为添加注释的一个例子,我们将把 第 7.2.1.2 节 “检查命令行参数” 的 feed.sh
和 penguin.sh
改的好一点。
michel ~/test>
catpenguin.sh
#!/bin/bash # This script lets you present different menus to Tux. He will only be happy # when given a fish. To make it more fun, we added a couple more animals. if [ "$menu" == "fish" ]; then if [ "$animal" == "penguin" ]; then echo -e "Hmmmmmm fish... Tux happy!\n" elif [ "$animal" == "dolphin" ]; then echo -e "\a\a\aPweetpeettreetppeterdepweet!\a\a\a\n" else echo -e "*prrrrrrrt*\n" fi else if [ "$animal" == "penguin" ]; then echo -e "Tux don't like that. Tux wants fish!\n" exit 1 elif [ "$animal" == "dolphin" ]; then echo -e "\a\a\a\a\a\aPweepwishpeeterdepweet!\a\a\a" exit 2 else echo -e "Will you read this sign?! Don't feed the "$animal"s!\n" exit 3 fi fimichel ~/test>
catfeed.sh
#!/bin/bash # This script acts upon the exit status given by penguin.sh if [ "$#" != "2" ]; then echo -e "Usage of the feed script:\t$0 food-on-menu animal-name\n" exit 1 else export menu="$1" export animal="$2" echo -e "Feeding $menu to $animal...\n" feed="/nethome/anny/testdir/penguin.sh" $feed $menu $animal result="$?" echo -e "Done feeding.\n" case "$result" in 1) echo -e "Guard: \"You'd better give'm a fish, less they get violent...\"\n" ;; 2) echo -e "Guard: \"No wonder they flee our planet...\"\n" ;; 3) echo -e "Guard: \"Buy the food that the Zoo provides at the entry, you ***\"\n" echo -e "Guard: \"You want to poison them, do you?\"\n" ;; *) echo -e "Guard: \"Don't forget the guide!\"\n" ;; esac fi echo "Leaving..." echo -e "\a\a\aThanks for visiting the Zoo, hope to see you again soon!\n"michel ~/test>
feed.shapple camel
Feeding apple to camel... Will you read this sign?! Don't feed the camels! Done feeding. Guard: "Buy the food that the Zoo provides at the entry, you ***" Guard: "You want to poison them, do you?" Leaving... Thanks for visiting the Zoo, hope to see you again soon!michel ~/test>
feed.shapple
Usage of the feed script: ./feed.sh food-on-menu animal-name
更多关于转义字符可以参考 第 3.3.2 节 “转义字符” 。下表给出 echo 命令能识别的顺序总揽:
表 8.1. echo命令使用的转义序列
序列 | 意义 |
---|---|
\a | 响铃。 |
\b | 退格。 |
\c | 强制换行。 |
\e | 退出。 |
\f | 清除屏幕Form feed. |
\n | 换行。 |
\r | 回车。 |
\t | 水平制表符。 |
\v | 垂直制表符。 |
\\ | 反斜杠。 |
\ONNN | 值为八进制值NNN(0到3个八进制数字)的8比特字符。 |
\NNN | 值为八进制值NNN(1到3个八进制数字)的8比特字符。 |
\xHH | 值为十六进制值(1或者2个十六进制数字)的8比特字符。 |
要得到更多关于 printf 命令的信息以及允许你格式化输出的方法,请参阅Bash Info页面。