Linux教程 - 管道和重定向
管道和重定向!
保持数据流动
介绍
在前两节中,我们看了一些可以为我们操作数据的过滤器。在本节中,我们将看到我们如何将它们结合在一起来执行更强大的数据操作。
本节涉及一些阅读。即使这些机制及其使用非常简单,但如果您希望有效使用这些机制,了解其行为的各种特征也很重要。
那么他们是什么?
我们在命令行上运行的每个程序都会自动连接三个数据流。
- STDIN(0) - 标准输入(数据输入到程序中)
- STDOUT(1) - 标准输出(由程序打印的数据,默认为终端)
- STDERR(2) - 标准错误(对于错误消息,也默认为终端)
管道和重定向是我们可以将程序和文件之间的这些流连接起来,以有趣和有用的方式引导数据的手段。
我们将在下面用几个例子来演示管道和重定向,但这些机制可以在命令行上的每个程序中使用,而不仅仅是我们在示例中使用的那些。
重定向到一个文件
通常情况下,我们会在屏幕上显示输出,这在大多数情况下都很方便,但有时我们可能希望将其保存到文件中作为记录,放入另一个系统或发送给其他人。大于运算符(>)向命令行指示我们希望程序输出(或发送到STDOUT的任何内容)以保存在文件中而不是打印到屏幕上。我们来看一个例子。
- LS
- barry.txt bob example.png firstfile foo1 video.mpeg
- ls> myoutput
- LS
- barry.txt bob example.png firstfile foo1 myoutput video.mpeg
- 猫myoutput
- barry.txt
- 短发
- example.png
- firstfile
- foo1
- MyOutput中
- video.mpeg
让我们分解一下:
- 第1行让我们先看看当前目录中的内容。
- 第3行现在我们将运行相同的命令,但是这次我们使用>来告诉终端将输出保存到文件myoutput中。你会注意到我们不需要在保存之前创建文件。如果终端不存在,终端将自动创建它。
- 第4行如您所见,我们的新文件已创建。
- 第6行让我们来看看在那里保存了什么。
一些观察
您会注意到,在上面的示例中,保存在文件中的输出在打印到屏幕时每行只有一个文件,而不是一行。原因是屏幕是已知的宽度,程序可以格式化它的输出以适应这种情况。当我们重定向时,它可能是一个文件,或者它可能在其他地方,所以最安全的选择是将其格式化为每行一个条目。这也可以让我们稍后更轻松地处理这些数据,因为我们将在页面的下方看到。
当管道和重定向时,实际数据总是相同的,但是这些数据的格式可能与通常打印到屏幕上的数据稍有不同。记住这一点。
您还会注意到我们创建的用于保存数据的文件也在我们的列表中。机制的工作方式是首先创建文件(如果它不存在),然后程序运行并输出保存到文件中。
保存到现有文件
如果我们重定向到一个不存在的文件,它会自动为我们创建。但是,如果我们保存到一个已经存在的文件中,那么它的内容将被清除,然后新的输出保存到它。
- 猫myoutput
- barry.txt
- 短发
- example.png
- firstfile
- foo1
- MyOutput中
- video.mpeg
- wc -l barry.txt> myoutput
- 猫myoutput
- 7 barry.txt
我们可以使用double大于运算符(>>)将新数据附加到文件中。
- 猫myoutput
- 7 barry.txt
- ls >> myoutput
- 猫myoutput
- 7 barry.txt
- barry.txt
- 短发
- example.png
- firstfile
- foo1
- MyOutput中
- video.mpeg
从文件重定向
如果我们使用小于运算符(<),那么我们可以用另一种方式发送数据。我们将从文件中读取数据,并通过它的STDIN流将其传送到程序中。
- wc -l myoutput
- 8 myoutput
- wc -l <myoutput
- 8
许多程序(正如我们在前面的章节中看到的)允许我们提供一个文件作为命令行参数,它将读取和处理该文件的内容。鉴于此,您可能会问为什么我们需要使用此操作员。上面的例子说明了一个微妙但有用的区别。您会注意到,当我们运行wc提供文件以作为命令行参数处理时,程序的输出中包含了已处理文件的名称。当我们运行它时,将文件的内容重定向到wc文件名不被打印。这是因为无论何时我们使用重定向或管道,数据都是匿名发送的。所以在上面的例子中,wc收到了一些要处理的内容,但它不知道它来自哪里,所以它可能不会打印这些信息。结果是,
我们可以很容易地将我们目前看到的两种形式的重定向合并为一个命令,如下面的示例所示。
- wc -l <barry.txt> myoutput
- 猫myoutput
- 7
重定向STDERR
现在我们来看看第三个是标准错误还是STDERR的流。这三个流实际上都有与它们相关的数字(在页面顶部的列表中的括号内)。STDERR是2号流,我们可以使用这些数字来识别流。如果我们在>操作符之前放置一个数字,那么它会重定向该流(如果我们不使用数字,就像我们迄今为止所做的那样,那么它默认为流1)。
- ls -l video.mpg blah.foo
- ls:无法访问blah.foo:没有这样的文件或目录
- -rwxr - r-- 1 ryan用户6 5月16日09:14 video.mpg
- ls -l video.mpg blah.foo 2> errors.txt
- -rwxr - r-- 1 ryan用户6 5月16日09:14 video.mpg
- cat errors.txt
- ls:无法访问blah.foo:没有这样的文件或目录
也许我们希望将正常输出和错误消息保存到一个文件中。这可以通过将STDERR流重定向到STDOUT流并将STDOUT重定向到文件来完成。我们首先重定向到一个文件然后重定向错误流。我们通过在流号码的前面放置一个&来识别流的重定向(否则它将重定向到名为1的文件)。
- ls -l video.mpg blah.foo> myoutput 2>&1
- 猫myoutput
- ls:无法访问blah.foo:没有这样的文件或目录
- -rwxr - r-- 1 ryan用户6 5月16日09:14 video.mpg
管道
到目前为止,我们已经处理向文件发送数据和从文件发送数据。现在我们来看一下从一个程序发送数据到另一个程序的机制。它被称为管道,我们使用的操作符是(|)(位于大多数键盘上的反斜杠(\)键之上)。该操作员所做的是将左侧程序的输出作为右侧程序的输入。在下面的例子中,我们将只列出目录中的前3个文件。
- LS
- barry.txt bob example.png firstfile foo1 myoutput video.mpeg
- ls | 头-3
- barry.txt
- 短发
- example.png
我们可以按照我们喜欢的方式将尽可能多的节目一起制作 在下面的例子中,我们然后将输出传送到尾部以便仅获得第三个文件。
- ls | 头-3 | 尾巴-1
- example.png
我们为程序提供的任何命令行参数都必须在该程序旁边。
我经常发现人们试图将他们的管道一气呵成地写出来,并在某处沿线犯了一个错误。然后他们认为这是一个点,但实际上这是另一点。他们浪费了大量的时间,试图解决不存在的问题,而没有看到存在的问题。如果你逐渐建立你的管道,那么你将不会陷入这个陷阱。运行第一个程序并确保它提供您期望的输出。然后添加第二个程序并再次检查,然后再添加第三个,依此类推。这会为你节省很多挫折。
你也可以组合管道和重定向。
- ls | 头-3 | tail -1> myoutput
- 猫myoutput
- example.png
更多示例
以下是一些更多的例子,可以让您了解您可以使用管道进行的各种事情。有许多事情你可以用管道来实现,而这些只是其中的一小部分。凭借经验和一点创造性思维,我相信你会发现更多的方式来使用管道让你的生活更轻松。
示例中使用的所有程序都是我们以前见过的程序。然而,我已经使用了一些我们尚未涉及的命令行参数。查看相关的手册页以了解他们的工作。你也可以自己尝试命令,逐步建立起来,看看每个步骤都在做什么。
在这个例子中,我们正在对目录列表进行排序,以便首先列出所有目录。
- ls -l / etc | tail -n +2 | 分类
- drwxrwxr-x 3 nagios nagcmd 4096 Mar 29 08:52 nagios
- drwxr-x--- 2 news news 4096 Jan 27 02:22 news
- drwxr-x--- 2 root mysql 4096 Mar 6 22:39 mysql
- ...
In this example we will feed the output of a program into the program less so that we can view it easier.
- ls -l /etc | less
- (Full screen of output you may scroll. Try it yourself to see.)
Identify all files in your home directory which the group has write permission for.
- ls -l ~ | grep '^.....w'
- drwxrwxr-x 3 ryan users 4096 Jan 21 04:12 dropbox
Create a listing of every user which owns a file in a given directory as well as how many files and directories they own.
- ls -l /projects/ghosttrail | tail -n +2 | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | sort | uniq -c
- 8 anne
- 34 harry
- 37 tina
- 18 ryan
Summary
- >
- Save output to a file.
- >>
- Append output to a file.
- <
- Read input from a file.
- 2>
- Redirect error messages.
- |
- 将一个程序的输出作为输入发送到另一个程序。
- 流
- 您可以在命令行上运行的每个程序都有3个流,STDIN,STDOUT和STDERR。
活动
让我们修改一些数据:
- 首先,尝试将各种命令的输出保存到文件中。覆盖该文件并追加到它。确保你正在使用绝对路径和相对路径。
- 现在看看你是否只能列出目录/ etc中最后20个文件。
- 最后,看看您是否可以计算在主目录中有多少文件和目录具有执行权限。