Shell命令 下载本文

第 4 章 Shell 与 Vi 编辑器

它可以是普通的字母或者数字,也可以使用特殊字符来匹配不同的文本模式。我们稍后将

更详细地讨论正则表达式。grep 命令打印出所有符合指定规则的文本行。例如:

$ grep ?match_string? file

即从指定文件中找到含有字符串的行。

2. 正则表达式字符

Linux 定义了一个使用正则表达式的模式识别机制。Linux 系统库包含了对正则表达式 的支持,鼓励程序中使用这个机制。

遗憾的是 she11 的特殊字符辨认系统没有利用正则表达式,因为它们比 Shell 自己的缩 写更加讨厌和难用。Shell 的特殊字符和正则表达式是很相似的,但是为了正确的利用正则 表达式,用户必须了解两者之间的区别。

注意:由于正则表达式使用了一些特殊字符,所以所有的正则表达式都必须用单引号 括起来。

正则表达式字符可以包含某些特殊的模式匹配字符。句点匹配任意一个字符,相当于 shel1 的问号。紧接句号之后的星号匹配零个或多个任意字符,相当于 Shell 的星号。方括 号的用法跟 Shell 的一样,只是用^代替了!表示匹配不在指定列表内的字符。

表 4-4 列出了正则表达式的模式匹配字符。

表 4-4 字符表达式

. [list] [range] [^ ] 匹配单个任意字符 匹配字符串列表中的其中一个字符 匹配指定范围中的一个字符 匹配指定字符串或指定范围中以外的一个字符 表 4-5 列出了与上面配合使用的量词。

表 4-5 量词

* \\{n\\} \\{n,\\} \\{n,m\\} 匹配前一个字符零次或多次 匹配前一个字符 n 次 匹配前一个字符至少 n 次 匹配前一个字符 n 次至 m 次 表 4-6 列出了控制字符。

表 4-6 控制字符

^ $ \\

只在行头匹配正则表达式 只在行末匹配正则表达式 引用特殊字符

- 80 -

第 4 章 Shell 与 Vi 编辑器

控制字符是用来标记行头或者行尾的,支持统计字符串的出现次数。

- 81 -

第 4 章 Shell 与 Vi 编辑器

非特殊字符代表它们自己,如果要表示特殊字符需要在前面加上反斜杠。

例如:

help \\..$ ^...$

^[0-9]\\{3\\}[^0-9] ^\\([A-Z][A-Z]\\)*$

匹配包含 help 的行..

匹配倒数第二个字符是句点的行 匹配只有 3 个字符的行 匹配以 3 个数字开头跟着是一个非数字字符的行 匹配只包含偶数个大写字母的行

4.1.4 输入输出重定向与管道

1. 重定向 所谓重定向,就是不使用系统的标准输入端口、标准输出端口或标准错误端口,而进

行重新的指定,所以重定向分为输入重定向、输出重定向和错误重定向。通常情况下重定 向到一个文件。在 Shell 中,要实现重定向主要依靠重定向符实现,即 Shell 是检查命令行 中有无重定向符来决定是否需要实施重定向。表 4-7 列出了常用的重定向符。

表 4-7 重定向符

重定向符 说明 实现输入重定向。输入重定向并不经常使用,因为大多数命令都 以参数的形式在命令行上指定输入文件的文件名。尽管如此,当使用 一个不接受文件名为输入多数的命令,而需要的输入又是在一个已存 在的文件中时,就能用输入重定向解决问题。 < 实现输出重定向。输出重定向比输入重定向更常用。输出重定向 使用户能把一个命令的输出重定向到一个文件中,而不是显示在屏幕 >或>> 上。很多情况下都可以使用这种功能。例如,如果某个命令的输出很 多,在屏幕上不能完全显示,即可把它重定向到一个文件中,稍后再 用文本编辑器来打开这个文件。 2>或 2>> &> 实现错误重定向。 同时实现输出重定向和错误重定向。 要注意的是,在实际执行命令之前,命令解释程序会自动打开(如果文件不存在则自

动创建)且清空该文件(文中己存在的数据将被删除)。当命令完成时,命令解释程序会正 确地关闭该文件,而命令在执行时并不知道它的输出流已被重定向。

下面举几个使用重定向的例子:

(1)将 ls 命令生成的/tmp 目录的一个清单存到当前目录中的 dir 文件中。

$ ls –l /tmp >dir

(2)将 ls 命令生成的/etc 目录的一个清单以追加的方式存到当前目录中的 dir 文件中。

$ ls –l /tmp >>dir

- 82 -

第 4 章 Shell 与 Vi 编辑器

(3)passwd 文件的内容作为 wc 命令的输入。

$ wc

(4)将命令 myprogram 的错误信息保存在当前目录下的 err_file 文件中。

$ myprogram 2>err_file

(5)将命令 myprogram 的输出信息和错误信息保存在当前目录下的 output_file 文件

中。

$ myprogram &>output_file

(6)将命令 ls 的错误信息保存在当前目录下的 err_file 文件中。

$ ls –l 2>err_file

注意:该命令并没有产生错误信息,但 err_file 文件中的原文件内容会被清空。 当我们输入重定向符时,命令解释程序会检查目标文件是否存在。如果不存在,命令 解释程序将会根据给定的文件名创建一个空文件;如果文件已经存在,命令解释程序则会 清除其内容并准备写入命令的输出到结果。这种操作方式表明:当重定向到一个已存在的 文件时需要十分小心,数据很容易在用户还没有意识到之前就丢失了。

Bash 输入输出重定向可以通过使用下面选项设置为不覆盖己存在文件:

$ set -o noclobber

这个选项仅用于对当前命令解释程序输入输出进行重定向,而其他程序仍可能覆盖已 存在的文件。

(7)/dev/null

空设备的一个典型用法是丢弃从 find 或 grep 等命令送来的错误信息:

$ grep delegate /etc/* 2>/dev/null

上面的 grep 命令的含义是从/etc 目录下的所有文件中搜索包含字符串 delegate 的所有 的行。由于我们是在普通用户的权限下执行该命令,grep 命令是无法打开某些文件的,系 统会显示一大堆“未得到允许”的错误提示。通过将错误重定向到空设备,我们可以在屏 幕上只得到有用的输出。

2. 管道

许多 Linux 命令具有过滤特性,即一条命令通过标准输入端口接收一个文件中的数据, 命令执行后产生的结果数据又通过标准输出端口送给后一条命令,作为该命令的输入数据。 后一条命令也是通过标准输入端口接收输入数据。

Shell 提供管道命令“|”将这些命令前后衔接在一起,形成一个管道线。格式为:

命令 1|命令 2|??|命令 n

管道线中的每一条命令都作为一个单独的进程运行,每一条命令的输出作为下一条命

令的输入。由于管道线中的命令总是从左到右顺序执行的,因此管道线是单向的。 管道线的实现创建了 Linux 系统管道文件并进行重定向,但是管道不同于 I/O 重定向, 输入重定向导致一个程序的标准输入来自某个文件,输出重定向是将一个程序的标准输出 写到一个文件中,而管道是直接将一个程序的标准输出与另一个程序的标准输入相连接,

- 83 -

第 4 章 Shell 与 Vi 编辑器

不需要经过任何中间文件。

例如:

$who >tmpfile

我们运行命令 who 来找出谁已经登录进入系统。该命令的输出结果是每个用户对应一 行数据,其中包含了一些有用的信息,我们将这些信息保存在临时文件中。

现在我们运行下面的命令:

$ wc -l

该命令会统计临时文件的行数,最后的结果是登陆入系统中的用户的人数。 我们可以将以上两个命令组合起来。

$ who|wc -l

管道符号告诉命令解释程序将左边的命令(在本例中为 who)的标准输出流连接到右 边的命令(在本例中为 wc -l)的标准输入流。现在命令 who 的输出不经过临时文件就可 以直接送到命令 wc 中了。

下面再举几个使用管道的例子:

(1)以长格式递归的方式分屏显示/etc 目录下的文件和目录列表。

$ ls –Rl /etc | more

(2)分屏显示文本文件/etc/passwd 的内容。

$ cat /etc/passwd | more

(3)统计文本文件/etc/passwd 的行数、字数和字符数。

$ cat /etc/passwd | wc

(4)查看是否存在 john 用户帐号。

$ cat /etc/passwd | grep john

(5)查看系统是否安装了 apache 软件包。

$ rpm –qa | grep apache

(6)显示文本文件中的若干行。

$ tail +15 myfile | head -3

管道仅能操纵命令的标准输出流。如果标准错误输出未重定向,那么任何写入其中的 信息都会在终端显示屏幕上显示。管道可用来连接两个以上的命令。由于使用了一种被称 为过滤器的服务程序,多级管道在 Linux 中是很普遍的。过滤器只是一段程序,它从自己 的标准输入流读入数据,然后写到自己的标准输出流中,这样就能沿着管道过滤数据。在 下例中:

$ who|grep ttyp| wc –l

who 命令的输出结果由 grep 命令来处理,而 grep 命令则过滤掉(丢弃掉)所有不包 含字符串\的行。这个输出结果经过管道送到命令 wc,而该命令的功能是统计剩余的 行数,这些行数与网络用户的人数相对应。

- 84 -