引言

Linux 内置的重定向功能为您提供了一组健壮的工具,用于使各种任务更容易完成。 无论您是在编写复杂的软件还是通过命令行执行文件管理,了解如何操作环境中的不同 i / o 流都将极大地提高您的生产力。

溪流

Linux 环境中的输入和输出分布在三个流中,这三个流是:

  • 标准输入(stdin)
  • standard output ( stdout )
  • 标准错误

这些数据流也被编号:

  • Stdin (0)
  • 标准输出(1)
  • (2)

在用户和终端之间的标准交互过程中,标准输入通过用户的键盘传输。 标准输出和标准错误以文本形式显示在用户的终端上。 这三条溪流合称为文本数据流。

标准输入

标准输入流通常将数据从用户传输到程序。 期望标准输入的程序通常从设备(如键盘)接收输入。 标准输入在到达 EOF (文件结束)时终止。 正如其名称所描述的,EOF 表示没有更多的数据需要读取。

要查看运行中的标准输入,请运行 cat 程序。 Cat 代表 concatenate,意思是链接或合并某物。 它通常用于组合两个文件的内容。 当单独运行时,cat 打开一个循环提示符。

cat

打开猫咪后,在它运行时键入一系列数字。

1
2
3
ctrl-d

当您键入一个数字并按下回车键时,您正在向正在运行的 cat 程序发送标准输入,该程序正在等待输入。 接下来,cat 程序将您的输入作为标准输出发送回终端显示器。

用户可以通过按 ctrl-d 键输入 EOF,cat 程序接收到 EOF 后停止运行。

标准输出

标准输出写入程序生成的数据。 当标准输出流没有重定向时,它将向终端输出文本。 试试下面的例子:

echo Sent to the terminal through standard output

在没有任何附加选项的情况下使用时,echo 命令将显示在命令行上传递给它的任何参数。 参数是程序接收到的东西。

不带任何参数运行 echo:

echo

它将返回一个空行,因为没有参数。

标准错误

标准错误写入程序在执行过程中失败时产生的错误。 与标准输出一样,此流的默认目的地是终端显示。

当一个程序的标准错误流通过管道传输到另一个程序时,管道数据(由程序错误组成)也同时发送到终端。

让我们看一个使用 ls 命令的标准错误的基本例子。 ls 列出一个目录的内容。

当不带参数运行时,ls 列出了工作目录中的内容。 如果 ls 以一个目录作为参数运行,它将列出所提供目录的内容。

ls % 

由于% 不是一个现有的目录,这将发送以下文本到标准错误:

ls: cannot access %: No such file or directory

流重定向

Linux 包含每个流的重定向命令。 这些命令将标准输出写入文件。 如果目标是一个不存在的文件(通过单括号或双括号命令) ,那么在写之前将创建一个具有该名称的新文件。

带有单个括号的命令将覆盖目标的现有内容。

覆盖

  • - 标准输出
  • - 标准输入
  • 2标准误差

带双括号的命令不会覆盖目标的现有内容。

Append

  • - 标准输出
  • - 标准输入
  • 2标准误差

让我们来看一个例子:

cat > write_to_me.txt
a
b
c
ctrl-d

在这里,cat 被用来写入一个文件,这个文件是作为循环的结果创建的。

使用 cat 查看 write to me.txt 的内容:

cat write_to_me.txt

它应该包括以下内容:

a
b
c

重定向 cat 再次写给 me.txt,并输入三个数字。

cat > write_to_me.txt
1
2
3
ctrl-d

当您使用 cat 查看 write to me.txt 时,您将看到以下内容:

1
2
3

之前的内容不再存在,因为文件被单括号命令覆盖。

再执行一次 cat 重定向,这次使用双括号:

cat >> write_to_me.txt
a
b
c
ctrl-d

再次打开 write to me.txt,你会看到:

1
2
3
a
b
c

文件现在包含 cat 的两个用法的文本,因为第二个用法没有覆盖第一个用法。

水管

管道用于将流从一个程序重定向到另一个程序。 当一个程序的标准输出通过管道发送到另一个程序时,第一个程序的数据(由第二个程序接收)将不会显示在终端上。 只显示由第二个程序返回的经过筛选的数据。

Linux 管道由一个竖线表示。

*|*

使用管道的命令示例:

ls | less

它接受 ls 的输出,这个输出显示你的工作目录文件的内容,然后把它传送到 less 程序。 Less 一次一行地显示发送给它的数据。

Ls 通常跨多行显示目录内容。 当运行次数较少时,每个条目将放置在一个新行上。

虽然管道的功能看起来与和(标准输出重定向)类似,但区别在于管道将数据从一个命令重定向到另一个命令,而且用于专门重定向到文件。

过滤器

过滤器是改变管道重定向和输出的命令。 注意,过滤器命令也是标准的 Linux 命令,不需要管道就可以使用。

  • Find-Find 返回文件名与传递给 Find 的参数匹配的文件。
  • Grep-Grep 返回与传递给 Grep 的字符串模式匹配的文本。
  • Tee-Tee 将标准输入重定向到标准输出和一个或多个文件。
  • Tr-tr 查找并用另一个字符串替换一个字符串。
  • Wc-wc 计算字符,行数和词数。

例子

现在已经介绍了重定向、管道和基本过滤器,接下来看一些基本的重定向模式和示例。

命令文件

此模式将命令的标准输出重定向到文件。

ls ~ > root_dir_contents.txt

上面的命令将系统根目录的内容作为标准输出传递,并将输出写入一个名为 root dir contents.txt 的文件。 它将删除文件中任何先前的内容,因为它是一个单括号命令。

命令 / dev / null

/ dev / null 是一个特殊的文件,用于删除重定向到它的任何数据。 它用于丢弃不需要的标准输出,否则可能会干扰命令或脚本的功能。 发送到 / dev / null 的任何输出都将被丢弃。 将来,在编写 shell 脚本时,您可能会发现将标准输出和标准错误重定向到 / dev / null 的实践。

ls > /dev/null

这个命令通过将 ls 命令传递给 / dev / null 来丢弃从命令 ls 返回的标准输出流。

命令2文件

此模式将命令的标准错误流重定向到文件,并覆盖现有内容。

mkdir '' 2> mkdir_log.txt

这将重定向由无效目录名“引发的错误,并将其写入 log.txt。 请注意,错误仍然发送到终端并显示为文本。

命令文件

此模式将命令的标准输出重定向到文件,而不覆盖文件的现有内容。

echo Written to a new file > data.txt
echo Appended content to an existing file >> data.txt

这两个命令首先将用户通过 echo 输入的文本重定向到一个新文件。 然后,它将第二个 echo 命令接收到的文本附加到现有文件,而不改写其内容。

命令2文件

上面的模式将命令的标准错误流重定向到一个文件,而不覆盖该文件的现有内容。 这种模式对于为程序或服务创建错误日志非常有用,因为日志文件不会在每次写入文件时擦除其以前的内容。

find '' 2> stderr_log.txt
wc '' 2>> stderr_log.txt

上面的命令将无效的 find 参数导致的错误消息重定向到名为 stderr log.txt 的文件。 然后,它将由无效 wc 参数引起的错误消息追加到同一文件中。

命令 | 命令

将第一个命令的标准输出重定向到第二个命令的标准输入。

find /var lib | grep deb

该命令在 / var 及其子文件夹中搜索匹配字符串 deb 的文件名和扩展名,并返回文件的文件路径,每个路径中的匹配部分用红色高亮显示。

命令 | tee 文件

这个模式(包括 tee 命令)将命令的标准输出重定向到一个文件并覆盖其内容。 然后,它在终端中显示重定向的输出。 如果文件不存在,它将创建一个新文件。

在此模式的上下文中,通常使用 tee 来查看程序的输出,同时将其保存到文件中。

wc /etc/magic | tee magic_count.txt

这将 magic 文件(Linux shell 用于确定文件类型)中的字符、行和词的计数通过管道传送到 tee 命令,后者随后将 wc 的输出分为两个方向,并将其发送到终端显示器和 magic count.txt 文件。 对于 tee 命令,想象字母 t。 字母的底部是初始数据,顶部是被分成两个不同方向的数据(标准输出和终端)。

可以使用多个管道将输出重定向到多个命令和 / 或过滤器之间。

命令 | command | command 文件

此模式预定向第一个命令的标准输出,并通过后两个命令对其进行筛选。 然后将最终结果附加到文件中。

ls ~ | grep *tar | tr e E >> ls_log.txt

首先在根目录(~)中运行 ls,并将结果管道化为 grep 命令。 在这种情况下,grep 返回文件名或扩展名中包含 tar 的文件列表。

然后,grep 的结果通过管道传递给 tr,后者将字母 e 的出现替换为 e,因为 e 作为第一个参数(要搜索的字符串)传递,而 e 作为第二个参数传递(替换第一个参数的所有匹配的字符串)。 然后将最终结果附加到文件 ls log.txt 中,如果该文件不存在,则创建该文件。

总结

学习如何使用 Linux 命令行内置的重定向功能可能有点令人生畏,但是在完成本教程之后,您就可以很好地掌握这一技能了。 现在您已经了解了重定向和管道的基本工作原理,您将能够开始尝试进入 shell 脚本世界,该脚本将频繁使用本指南中强调的程序和模式。

如果您想更深入地了解本教程中介绍的命令,可以使用 man 命令 | less。 例如:

man tee | less

这将显示 tee 程序可用的完整命令列表。 您可以使用此模式显示任何 Linux 命令或程序的信息和使用选项。

在谷歌上搜索特定的命令,或者你想在命令行中做的事情(例如“删除目录中以大写字母开头的所有文件”) ,在你需要使用命令行完成特定任务时也会很有帮助。