一.学习内容
1.在本课中,我们将展示命令行最酷的特性。它被称为I/O重定向。“I/O”代表输入/输出,使用这个工具,您可以重定向命令的输入和输出进出文件,以及将多个命令连接到强大的命令管道中。为了展示这个功能,我们将介绍以下命令:
cat连接文件
sort对文本行进行排序
uniq报告或省略重复行
grep打印匹配模式的行
wc打印每个文件的换行、字和字节计数
head输出文件的第一部分
tail输出文件的最后一部分
tee从标准输入读取并写入标准输出和文件
二.标准输入,输出和错误
1.到目前为止,我们使用的许多程序都会产生某种输出。这种输出通常由两种类型组成。
•项目结果;也就是说,程序设计要产生的数据
•状态和错误信息,告诉我们程序是如何进行的
2.如果我们看一下像ls这样的命令,我们可以看到它在屏幕上显示其结果和错误消息。
与Unix“一切都是文件”的主题保持一致,像ls这样的程序实际上将它们的结果发送到一个称为标准输出(通常表示为stdout)的特殊文件,并将它们的状态消息发送到另一个文件
三.重定向标准输出
1.I/O重定向允许我们重新定义标准输出的位置。要将标准输出重定向到另一个文件而不是屏幕,我们使用>重定向操作符,后跟文件名。我们为什么要这么做?将命令的输出存储在文件中通常很有用。例如,我们可以告诉shell将ls命令的输出发送到文件ls-output.txt而不是屏幕
2.在这里,我们创建了/usr/bin目录的长清单,并将结果发送到文件ls-output.txt。让我们检查一下命令的重定向输出,如下所示:
3.很好,一个漂亮的大文本文件。如果我们查看带有less的文件,我们将看到文件ls-output.txt确实包含ls命令的结果。
4.现在,让我们重复我们的重定向测试,但这一次有所改变。我们将把目录名更改为不存在的目录名。
5.我们收到一条错误信息。这是有意义的,因为我们指定了不存在的目录/bin/usr,但是为什么错误消息显示在屏幕上,而不是重定向到文件ls-output.txt?答案是ls程序不会将错误消息发送到标准输出。
相反,像大多数编写良好的Unix程序一样,它将错误消息发送给标准错误。因为我们只重定向了标准输出而不是标准错误,所以错误消息仍然被发送到屏幕上。稍后我们将看到如何重定向标准错误,但首先让我们看看输出文件发生了什么。
6.该文件现在的长度为零!这是因为当我们使用>重定向操作符重定向输出时,目标文件总是从头重写。因为我们的ls命令没有生成任何结果,只有一条错误消息,所以重定向操作开始重写文件,然后因为错误而停止导致它被截断。事实上,如果我们需要截断一个文件(或者创建一个新的空文件),我们可以使用这样的技巧:
7.简单地使用重定向操作符,前面没有任何命令,将截断现有文件或创建一个新的空文件。
那么,我们如何将重定向输出附加到文件中,而不是从一开始就覆盖文件呢?为此,我们使用>>重定向操作符,如下所示:
8.使用>>操作符将导致输出被追加到文件中。
如果文件不存在,就像使用了>操作符一样创建它。让我们来验证一下。
9.我们重复该命令三次,得到的输出文件是原来的三倍大。
四.重定向标准错误
1.重定向标准错误缺乏专用重定向操作符的便利性。为了重定向标准错误,我们必须引用它的文件描述符。程序可以在几个编号的文件流中的任何一个上产生输出。虽然我们将前三个文件流称为标准输入、输出和错误,但shell在内部将它们引用为文件描述符0、1和
2,分别。shell提供了使用文件描述符号重定向文件的表示法。因为标准错误与文件描述符2相同,所以我们可以用t重定向标准错误
2.文件描述符2被放在重定向操作符之前,用于执行将标准错2》误重定向到文件ls-error.txt的操作。
3.将标准输出和标准错误重定向到一个文件
4.在某些情况下,我们可能希望将命令的所有输出捕获到单个文件中。为此,我们必须同时重定向标准输出和标准错误。有两种方法可以做到。这里显示的是传统的方法,它适用于旧版本的shell:
5.使用这种方法,我们执行了两次重定向。首先,我们将标准输出重定向到文件ls-output.txt,然后使用符号2>&1将文件描述符2(标准错误)重定向到文件描述符1(标准输出)。
6.注意重定向的顺序是重要的
标准错误的重定向必须始终在重定向标准输出之后发生,否则它将不起作用。下面的示例将标准错误重定向到文件ls-output.txt:
7.如果顺序更改为以下,则标准错误将直接显示在屏幕上:
8.最新版本的bash提供了第二种更精简的方法来执行这种组合重定向,如下所示:
9.在本例中,我们使用&>符号将标准输出和标准错误重定向到文件ls-output.txt。你也可以像这样将标准输出和标准错误流附加到单个文件中:
[me@linuxbox ~]$ ls -l /bin/usr &>> ls-output.txt
五.处理不需要的输出
1.有时候“沉默是金”,我们不想要命令的输出;我们只是想把它扔掉。这尤其适用于错误和状态消息。通过将输出重定向到一个名为/dev/null的特殊文件,系统提供了一种方法来做到这一点这个文件是一个系统设备,通常称为位桶,它接受输入,不处理输入。为了抑制来自命令的错误消息,我们这样做:
2./dev/null在Unix中
位桶是一个古老的Unix概念,由于它的通用性,它出现在Unix文化的许多部分。当有人说他们将你的评论发送到/dev/null时,现在你知道这是什么意思了。有关更多示例,请参阅Wikipedia关于/dev/null的文章
六.重定向标准输入
1.到目前为止,我们还没有遇到任何使用标准输入的命令(实际上我们有,但稍后我们将揭示这一点),因此我们需要介绍一个。
2.cat:连接文件
cat命令读取一个或多个文件,并将它们复制到标准输出中,如下所示:
假设我们下载了一个被分割成多个部分的大文件(多媒体文件在Usenet上通常是这样分割的),我们希望将它们重新连接在一起。如果文件命名如下:
这些都很好,但是这和标准输入有什么关系呢?还没有,但我们试试别的吧。如果我们不带参数输入cat会发生什么?
如果cat没有给定任何参数,它将从标准输入读取,并且由于标准输入在默认情况下是连接到键盘的,因此它正在等待我们键入一些东西!尝试添加以下文本并按enter键:
记得在最后键入ctrl-D。使用命令行,我们实现了世界上最愚蠢的文字处理器!要查看结果,可以使用cat再次将文件复制到stdout。
在我们继续之前,请查看cat的手册页,因为它有几个有趣的选项。
六.Pipelines
1. 命令从标准输入读取数据并将其发送到标准输出的能力被称为管道的shell特性所利用。使用管道操作符|,一个命令的标准输出可以通过管道连接到另一个命令的标准输入。
还记得我们说过有一个我们已经知道可以接受标准输入的吗?它是更少。我们可以使用less逐页显示将结果发送到标准输出的任何命令的输出。
Command1 > file1 Command1 | command2
很多人在学习管道时都会尝试以下操作,“只是为了看看会发生什么”:command1 > command2
回答:有时候真的很糟糕。
下面是一位管理基于linux的服务器设备的读者提交的实际示例。作为超级用户,他这样做了:
# CD /usr/bin
# ls > less
第一个命令将它放在大多数程序存储的目录中,第二个命令告诉shell使用ls命令的输出更少地覆盖文件。由于/usr/bin目录已经包含了一个名为less的文件(less程序),第二个命令用ls中的文本覆盖less程序文件,从而破坏了系统上的less程序。
这里的教训是,重定向操作符会静默地创建或覆盖文件,因此您需要非常尊重它。
七.uniq:报告或省略重复行
1.uniq命令通常与sort一起使用。Uniq接受来自标准输入或单个文件名参数(参见Uniq手册页了解详细信息)的排序数据列表,默认情况下,从列表中删除任何重复项。所以,为了确保我们的列表没有重复的。第6章是,任何出现在/bin和/usr/bin目录下的同名程序,我们将把uniq添加到我们的管道中。
假设我们想要在程序列表中找到名称中嵌入了单词zip的所有文件。这样的搜索可能会让我们对系统中与文件压缩有关的一些程序有所了解。我们会这样做:
•-i,使grep在执行搜索时忽略大小写(通常搜索是区分大小写的)
•-v,告诉grep只打印那些不匹配模式head/tail的行:
有时您不需要命令的所有输出。您可能只需要前几行或最后几行。head命令打印文件的前10行,tail命令打印最后10行。默认情况下,这两个命令打印10行文本,但可以使用-n选项进行调整。
10.这些也可以在管道中使用:
11.Tail有一个允许您实时查看文件的选项。这对于在日志文件被写入时监视其进度非常有用。在下面的示例中,我们将查看/var/log中的消息文件(如果消息丢失,则查看/var/log /syslog文件)。在某些Linux发行版上执行此操作需要超级用户权限,因为/var/log/messages文件可能包含安全信息。
12.使用-f选项,tail将继续监视文件,当添加新行时,它们将立即出现在显示中。这个过程一直持续到您键入ctrl-C。
八.tee - 从标准输入和输出读取到标准输出和文件
1.为了与管道比喻保持一致,Linux提供了一个名为tee的命令,用于在管道上创建一个“tee”配件。tee程序读取标准输入并将其复制到标准输出(允许数据沿着管道继续)和一个或多个文件中。这对于在处理的中间阶段捕获管道的内容非常有用。
这里我们重复前面的一个例子,这一次包括tee在grep过滤管道内容之前将整个目录列表捕获到文件ls.txt中:
九.总结
与往常一样,请查看本章所介绍的每个命令的文档。我们只看到了它们最基本的用法。它们都有许多有趣的选择。随着我们获得Linux经验,我们将看到命令行的重定向特性非常有用解决专门的问题。有许多命令使用标准输入和输出,几乎所有命令行程序都使用标准错误来显示它们的信息消息。
Linux是关于想象力的
当我被要求解释Windows和Linux之间的区别时,我经常使用一个玩具类比。
Windows就像一个Game Boy。你去商店买了一个崭新的盒子。你把它带回家,打开它,玩它。漂亮的画面,可爱的声音。但过了一段时间,你就会厌倦它附带的游戏,所以你会回到商店购买另一款游戏。这样的循环不断重复。最后,你回到商店,对柜台后的工作人员说:“我想要一款具有这种功能的游戏!,却被告知不存在这样的游戏,因为它没有“市场需求”。然后你说:“但我只需要改变这一件事!”背后的人然后你说:“但我只需要改变这一件事!”柜台后面的人说你不能换。所有的游戏都被密封在他们的墨盒里。你发现你的玩具仅限于别人认为你需要的游戏。
另一方面,Linux就像世界上最大的安装工具。你打开它,里面是一大堆零件。有很多钢支柱、螺丝、螺母、齿轮、滑轮、马达,还有一些关于建造什么的建议。所以,你开始摆弄它。你提出一个又一个建议。过了一段时间,你会发现你对做什么有自己的想法。你再也不用去商店了,因为你已经有了你需要的一切。
安装组呈现出你想象的形状。它做你想要的。
当然,你对玩具的选择是个人的事情,那么你觉得哪种玩具更令人满意呢?