《UNIX编程环境》——5.7 pick命令:空格和参数

5.7 pick命令:空格和参数

我们已经接触了书写shell的pick命令需要的多数命令。我们只需要一种新的机制来接收用户输入。shell内部命令read提供了这一功能,即从标准输入读一行正文,并把读到的文本(不含换行)赋给命名变量:

read最常用于注册时在.profile文件里设置环境,主要是建立shell环境变量,如TERM。

read只能读取标准输入,而且不能被重定向。shell内部命令(与控制流原语不同,如for)都不能使用>或<重定向:

这也许可以说是shell的一个缺陷,但这就是现实。幸运的是,重定向read外围的循环可以达到同样的目的。这是pick命令实现的关键:

echo-n抑制最后一个换行符,因此用户的响应可以打印在提示符的同一行。当然,提示符打印在/dev/tty上,因为这里的标准输出绝大多数情形下并不是终端。

break语句取自C语言,表示终止内部循环。上例中,输入q键时终止for循环。q为quit的缩写,易用,这一退出响应几乎已成为惯例,其他很多程序也采用q。

pick命令行参数里的空格是很有趣的:

要观察pick程序如何读取参数,运行pick并在每次提示符出现后按回车键。程序工作情况很好:for i适当地处理参数。我们还可以用其他方法写循环:

这种方式不能成功,因为循环中的操作数被重复扫描,这样第一个参数中的空格符将它变成两个参数。尝试使用引号括住参数$*:

还是不能正常工作,因为“$*”是由空格符分隔的所有参数连在一起构成的单个词。

可能的解决办法是,shell对字符串“$@”作特殊处理,并将它转换为严格的shell文件参数:

如果不用引号括住$@,它与$*相同;$@只有用双引号括住时才具有特殊性质。我们在overwrite程序中用它来保护用户的命令参数。

上述内容可以归纳为如下规则。

$*和$@扩展为参数,并被重复扫描;参数的空格符将字符串分成多个参数。

 “$*”表示shell文件的所有参数及其空格符连在一起作为单个词处理。

 “$@”与shell文件接收的参数等价,参数中的空格被忽略,其结果是等同于原来参数的一个单词列表。

如果pick程序没有参数,可以读取标准输入,所以可以使用命令

这里我们不研究这个版本的pick:它的复杂度和难以理解的程度远远超过下一章将要介绍的用C语言编写的程序。

下面练习中的前两个题目比较难,属于高级shell程序员教程的内容。

练习5-24 写一个pick程序,当命令行中没有参数支持时它从标准输入读取参数。程序应能正确处理空格符。能否处理q响应?如果不能,试做下一个练习。

练习5-25 虽然shell的内部命令如read和sed不能重定向,但shell本身可以暂时重定向。阅读sh(1)节中对exec命令的描述,考虑如果不调用子shell如何将read定向到/dev/tty。(可以先参阅第7章。)

练习5-26(比较容易) 在.profile文件里使用read初始化TERM和其他相关参数,如Tab停止位。

时间: 2025-01-28 11:42:23

《UNIX编程环境》——5.7 pick命令:空格和参数的相关文章

《UNIX编程环境》——导读

**前言**"UNIX安装的数量已经增加了10倍,预期还将更多." -UNIX程序员手册,1972年6月第2版 UNIX1操作系统是1969年首次在贝尔实验室的一台丢弃的DEC PDP-7计算机上启用的.当时Ken Thompson从Rudd Canaday.Doug McIlroy.Joe Ossanna和Dennis Ritchie那里获得理念和支持,编写了小型通用分时系统,其适用性能良好,足以吸引热心的用户,并最终为一台较大的计算机-PDP-11/20的购买提供了充分的可靠性.系

《UNIX编程环境》——5.6 zap:使用名字终止进程

5.6 zap:使用名字终止进程 kill命令只能通过指定进程号来终止进程.要终止某个后台进程时,一般要运行ps命令以得到进程标识号,然后再把它作为kill的参数输入.通过一个命令程序打印一个参数,再把这个参数手工输入到另一个命令中,这个方法似乎有些笨拙.为什么不写一个程序,如zap,自动完成这些工作呢? 原因之一是终止进程是个危险的操作,执行时必须小心谨慎.一个保险的办法是交互地运行zap,用pick命令选择要终止的进程. 先简要回顾一下pick的功能:pick顺次打印它的每个参数,并请求用户

《UNIX编程环境》——5.10 后记

5.10 后记 当需要编写一个新程序时,自然立刻会想到如何用你最喜欢的语言来编写这个程序.对我们来说,最常用的语言是shell. shell是一种很好的编程语言,虽然它的语法有些特殊.shell属于高级语言,它的操作对象为整个程序.由于shell是交互式语言,所以shell程序能够交互式地开发,可以逐级求精直至它能够令人满意地工作.如果是一个面向更多的用户,可以对shell程序进一步改造,使之更精巧和更实用,以满足广泛使用的需要.不能用shell程序高效地解决问题的情况微乎其微.如果遇到这种例外

《UNIX编程环境》——1.2 文件和常用命令

1.2 文件和常用命令 在UNIX系统中信息存储在文件中,它很像日常的办公室文件.每个文件有名字.内容.存放地点以及某些管理信息,诸如所有者以及文件大小等.文件可能是一封信,或者是人名及地址清单,或者是源程序,或者是供某个程序用的数据,甚至是程序的可执行形式以及其他的非文本类型材料. UNIX文件组织结构使你可以维护自己的文件而不会影响其他人的文件,并且也防止他人干涉你的文件.UNIX系统有大量的程序可操作文件,但是现在,我们只介绍最频繁使用的那些.第2章是关于文件系统的具体讨论,其中介绍了许多

《UNIX编程环境》——5.8 news命令:社团服务信息

5.8 news命令:社团服务信息 我们在第1章提到您的系统可以有一个news命令,用以报告用户社团方面的信息.大部分系统都提供新闻服务,尽管命令名和命令细节有所不同.这里给出一个news命令,不是要代替原有的本地命令,而旨在说明在shell里编写这样一个程序是多么地容易.比较两个news命令的实现会是件有趣的事情. 程序利用了一个基本事实,即各个新闻项目是分开存放的,每个文件包含一个新闻项目,存放在特定的目录下,譬如/usr/news.news(我们自己的news程序)将/usr/news目录

《UNIX编程环境》——1.4 shell

1.4 shell 当系统印出提示符$,你键入命令并得到了执行时,此时并不是内核在与读者对话,而是与一个称为命令解释器或外壳shell的在对话.shell是同date或who一样的普通程序,尽管它可以处理一些不同寻常的事.shell存在于用户和内核机制之间的事实对用户是有帮助的,有些会在这里说明.下面是三个要点. 文件名简写:可以通过指定文件名的模式来选取一套文件名作为程序的变量-shell会找出匹配该模式的文件名. 输入输出重定向:可以把任何程序的输出送到一个文件中而不是终端上,并当作来自文件

《UNIX编程环境》——第1章 初学UNIX 1.1起步

第1章 初学UNIX 第1章初学UNIX 什么是UNIX?狭义地看,它是一个分时操作系统内核,即一个控制计算机的资源并将其分配给用户的程序.它让用户运行其程序,并控制与机器连接的外围设备(硬盘.终端.打印机等),提供一个文件系统用以管理诸如程序.数据及文档等长期存储的信息. 广义地看,UNIX通常不仅包含内核,还包括一些基本程序,如编译器.编辑器.命令语言.用以复制和显示文件的程序等. 从更广的角度来看,UNIX可以包括由用户开发的.运行于用户的UNIX操作系统上的程序,如文档处理工具.统计分析

《UNIX编程环境》——5.5 overwrite:改写文件

5.5 overwrite:改写文件 sort排序命令有一个选顶-o,表示覆盖文件: 如果filel和file2是同一个文件,重定向符号>在排序之前就把输入文件截断.然而,加上-o选项的命令将能正常工作,因为在输出文件建立前,sort先将输入排序并存放在一个临时文件中. 很多其他命令也可用-o选择.例如,sed可以编辑文件如下: 要对所有这样的命令都加上选项-o显然是不现实的.另外,这种做法也不可取:最好是将功能集中起来处理,就像shell使用运算符>那样.我们给出一个程序overwrite完

《UNIX编程环境》——5.2 which

5.2 which 建立自己的命令版本,如cal命令的新版本,会带来一些其他的问题.最明显的例子是,如果Mary一起工作,并且以mary登录,则此时的cal还是标准的版本,除非Mary把新的cal命令连接到她的bin目录里.你可能会非常疑惑-原先的cal命令给出的错误信息不足以使人弄清发生错误的原因.但是这只是这类问题的一个例子.因为shell通过PATH指定的一组目录搜索命令,得到的可能不是所期望的版本.例如,键入一条命令:echo,而实际运行的文件全路径名可能是./echo./bin/ech