本文介绍了Linux环境中的输入输出流,重点讲解了标准输入、输出和错误的概念,以及如何通过重定向、管道和过滤器进行流操作,为提高命令行效率打下基础。
简介
Linux 中内置的重定向功能为您提供了一套强大的工具,可以优化许多工作流程。软件开发的“Unix 哲学”是制作每个都能很好地完成一件事的工具,这一哲学已经延续到现代命令行工具,这些工具在单独使用时非常强大,当它们组合在一起时则更加强大。无论您是在编写复杂的软件还是在命令行上工作,了解如何操作环境中的不同 I/O 流将极大地提高您的生产力。
先决条件
要按照本指南进行操作,您需要访问 Linux 服务器。如果您需要有关首次连接到服务器的信息,可以参考我们的连接指南,了解如何使用 SSH 连接到 Linux 服务器。
流
Linux 环境中的输入和输出分布在三个流中。这些流包括:
- 标准输入(stdin)
- 标准输出(stdout)
- 标准错误(stderr)
这些流也被编号:
- 标准输入(0)
- 标准输出(1)
- 标准错误(2)
在用户和终端之间的标准交互期间,标准输入来自用户的键盘。标准输出和标准错误以文本形式显示在用户的终端上。这三个流的集合被称为标准流。
标准输入
标准输入流通常将数据从用户传输到程序。期望标准输入的程序通常从设备(如键盘)接收输入。在本教程的后面部分,您将看到将一个程序的输出作为另一个程序的标准输入的示例。
标准输出
标准输出是程序生成的输出。当标准输出流没有被重定向时,它将直接将文本输出到终端。尝试输出一些任意文本,使用 echo
:
echo Sent to the terminal
Sent to the terminal
当没有任何额外选项时,echo
命令会输出传递给它的命令行参数。
不带任何参数运行 echo:
echo
它将返回一个空行。一些程序在没有提供参数的情况下不会执行任何操作。
标准错误
标准错误包含程序生成的错误。与标准输出一样,该流的默认目的地是终端显示。
让我们通过使用 ls 命令来看一个基本的标准错误示例。ls 用于列出目录的内容。
当没有参数运行 ls 时,它会列出当前目录中的内容。如果以目录作为参数运行 ls,则会列出所提供目录的内容。
ls %
由于 % 不是一个现有的目录,这将向标准错误发送以下文本:
ls: 无法访问 %: 没有那个文件或目录
程序不必崩溃或完成运行才能生成标准错误,某些输出是发送到标准输出或标准错误取决于程序的行为。它们在任何方面都没有技术上的不同 —— 只是一个输出流被保留用于错误消息,并且一些工具会假定标准错误为空意味着程序成功运行。一些程序甚至会在不崩溃或未能产生预期输出的情况下将次要错误输出到标准错误。这只是一种将预期输出与非预期输出分开的约定。
流重定向
Linux 包括每个流的重定向命令。这些命令可用于将标准输出或标准错误写入文件。如果写入一个不存在的文件,将在写入之前创建一个具有该名称的新文件。
带有单个括号的命令覆盖目标的现有内容。
覆盖
- > - 标准输出
- < - 标准输入
- 2> - 标准错误
带有双括号的命令不会覆盖目标的现有内容。
追加
- >> - 标准输出
- << - 标准输入
- 2>> - 标准错误
管道
管道用于将一个程序的流重定向到另一个程序。当一个程序的标准输出通过管道发送到另一个程序时,第一个程序的输出将被用作第二个程序的输入,而不是被打印到终端。只有第二个程序返回的数据将被显示。
Linux 的管道由竖线表示:|
以下是使用管道的命令示例:
ls | less
这将获取 ls
的输出(显示当前目录的内容)并管道到 less
程序。less
逐行显示发送到它的数据。
ls
通常在多行中显示目录内容。当您通过 less 运行它时,每个条目都会放在新行上。
尽管管道的功能可能看起来类似于 >
和 >>
,但区别在于管道将数据从一个命令重定向到另一个命令,而 > 和 >> 用于将数据重定向到文件。
过滤器
过滤器 是一类通常与从另一个程序输出的管道一起使用的程序。其中许多程序也可以单独使用,但它们特别好地展示了管道行为。
- find - 返回文件名与传递给 find 的参数匹配的文件。
- grep - 返回与传递给 grep 的字符串模式匹配的文本。
- tee - 将标准输入重定向到标准输出和一个或多个文件。
- tr - 查找并替换一个字符串为另一个字符串。
- wc - 计算字符数、行数和单词数。
示例
现在您已经了解了重定向、管道和基本过滤器,让我们来看一些常见的重定向模式和示例。
command > file
模式将命令的标准输出重定向到一个文件。
ls ~ > root_dir_contents.txt
上面的命令将您的主目录 (~
) 的内容作为标准输出传递,并将输出写入名为 root_dir_contents.txt
的文件。它将删除文件中的任何先前内容,因为它是一个单括号命令。
command > /dev/null
模式将标准输出重定向到无处。/dev/null
是一个特殊文件,用于丢弃重定向到它的任何数据。它用于丢弃不需要的标准输出,否则可能会干扰命令或脚本的功能。发送到 /dev/null
的任何输出都将被丢弃。
ls > /dev/null
此命令通过将其传递到 /dev/null 来丢弃从命令 ls 返回的标准输出流。
command 2> file
模式将命令的标准错误流重定向到一个文件,覆盖现有内容。
mkdir '' 2> mkdir_log.txt
这将重定向由无效目录名称 ''
引发的错误,并将其写入 log.txt
。请注意,错误仍然会发送到终端并显示为文本。
command >> file
模式将命令的标准输出重定向到一个文件,而不覆盖文件的现有内容。
echo Written to a new file > data.txt echo Appended content to an existing file >> data.txt
这一对命令首先通过 echo 将用户输入的文本重定向到一个新文件。然后,它将第二个 echo 命令接收到的文本附加到现有文件,而不覆盖其内容。
上述 command 2>> file
模式将命令的标准错误流重定向到一个文件,而不覆盖文件的现有内容。这种模式对于为程序或服务创建错误日志很有用,因为日志文件不会在每次写入文件时擦除其先前的内容。
find '' 2> stderr_log.txt wc '' 2>> stderr_log.txt
上述命令将由无效的 find 参数引发的错误消息重定向到名为 stderr_log.txt 的文件。然后将由无效的 wc 参数引发的错误消息附加到同一文件中。
command | command
模式将第一个命令的标准输出重定向到第二个命令的标准输入。
find /var lib | grep deb
此命令在 /var 及其子文件夹中搜索与字符串 deb
匹配的文件名和扩展名,并返回文件的文件路径,其中每个路径中匹配的部分以红色突出显示。
command | tee file
模式(包括 tee
命令)将命令的标准输出重定向到一个文件并覆盖其内容。然后,它在终端显示重定向的输出。如果文件不存在,则创建一个新文件。
在这种模式的上下文中,tee
通常用于同时查看程序的输出并将其保存到文件中。
wc /etc/magic | tee magic_count.txt
这将管道 /etc/magic
文件中的字符数、行数和单词数(Linux shell 用于确定文件类型的文件)到 tee 命令,然后将 wc
的输出分成两个方向,并将其发送到终端显示和 magic_count.txt
文件。对于 tee 命令,可以想象字母 T。字母的底部部分是初始数据,顶部部分是数据被分成两个不同方向(标准输出和终端)的部分。
可以使用多个管道将输出重定向到多个命令和/或过滤器。
结论
学习如何使用内置于 Linux 命令行中的重定向功能是一项至关重要的技能。现在您已经了解了重定向和管道的基础知识,您将能够开始进入 shell 脚本的世界,该脚本经常使用本指南中突出显示的程序和模式。
在需要使用命令行完成特定任务时,搜索特定命令或您想要在命令行中执行的任务也可能会很有帮助(例如“删除以大写字母开头的目录中的所有文件”)。