要了解重定向和管道的规则,我们需要引入一个前文并未引入的概念。绝大部分 UNIX® 进程(包括图形应用程序,但不包括绝大多数守护程序)至少使用三个文件描述符:标准输入、标准输出和标准错误输出。它们相应的序号是 0、1 和 2。一般来说,这三个描述符与该进程启动的终端相关联,其中输入为键盘。重定向和管道的目的是重定向这些描述符。本节中的实例将帮助您更好地了解这些概念。
假设您需要 images
目录下以 .png
结尾的文件列表[15]。而该列表很长,因此您想要将其保存至某个文件,然后等您有空的时候再看。您可以输入以下命令:
$ ls images/*.png 1>file_list
这表示把该命令的标准输出(1
)重定向到(>
)file_list
文件。其中的 >
操作符是输出重定向符。如果要重定向到的文件不存在,它将被创建;不过如果它已经存在,那么它先前的内容将被覆盖。不过,该操作符默认的描述符就是标准输出,因此就不用在命令行上特意指出。所以,上述命令可以简化为:
$ ls images/*.png >file_list
其结果是一样的。然后您就可以用某个文本文件查看器(比如 less)来查看。
现在,假定您想要知道这样的文件有多少。不用手工计数,您可以使用 wc (单词计数(Word Count))这个工具。使用其 -l
选项将在标准输出上显示文件的行数。所以,您可以:
$ wc -l 0<file_list
就可以得到期望的结果。其中的 <
操作符是输入重定向符,并且其默认重定向描述符是标准输入(即 0
)。因此您只需:
$ wc -l <file_list
假定您又想去掉其中所有文件的“扩展名”,并将结果保存到另一个文件。要完成这一功能可以使用 sed (流编辑器(Stream EDitor))。您只要将 sed 的标准输入重定向为 file_list
,并将其输出重定向到结果文件 the_list
。
$ sed -e 's/\.png$//g' <file_list >the_list
您所需要的就已被创建,并等待您在有空的时候用任何查看器查看。
重定向标准错误输出也很有用。例如:您会想要知道在 /shared
中有哪些目录您不能够访问。一个办法是递归地列出该目录并重定向错误输出到某个文件,并且不要显示标准输出:
$ ls -R /shared >/dev/null 2>errors
这表示标准输出将被重定向到(>
)/dev/null
(所有输出到此特殊文件的东西都将被丢弃,即不显示标准输出),并将标准错误输出(2
)重定向到(>
)errors
文件。
管道在某种程度上是输入和输出重定向的结合。其原理同物理管道类似:一个进程向管道的一端发送数据,而另一个进程从该管道的另一端读取数据。管道符是 |
。让我们再来看看上述文件列表的例子。假设您想直接找出有多少对应的文件,而不想先将它们保存到一个临时文件,您可以:
$ ls images/*.png | wc -l
这表示将 ls 命令的标准输出(即文件列表)重定向到 wc 命令的输入。这样您就直接得到了想要的结果。
$ ls images/*.png | sed -e 's/\.png$//g' >the_list
$ ls images/*.png | sed -e 's/\.png$//g' | less
管道和重定向不仅仅只能用于人类可以阅读的文本文件。例如下述来自 终端
的命令:
$ xwd -root | convert - ~/my_desktop.png
将把您桌面的截屏保存到您个人目录中的 my_desktop.png
文件[16]。