如何在Linux上使用管道

时间:2020-01-09 10:39:52  来源:igfitidea点击:

使用Linux管道来编排命令行实用程序的协作方式。通过利用一系列独立命令并将它们变成专心致志的团队,简化复杂的流程并提高生产率。我们向我们展示如何。

管道无处不在

管道是Linux和类似Unix的操作系统具有的最有用的命令行功能之一。管道以无数方式使用。不仅在我们网站上,在任何网站上查看任何Linux命令行文章,我们都会发现管道经常出现。我回顾了iGiftIdea的Linux文章,并在管道中以一种或者另一种方式使用管道。

Linux管道允许我们执行Shell开箱即用的操作。但是,由于Linux的设计理念是要有许多小型实用程序,它们可以很好地执行其专用功能,并且不需要不必要的功能,因此只能做一件事并做到最好。另一个。我们输入的每个命令都会为团队带来其独特的才能,很快我们就会发现自己已经组建了一支制胜之队。

一个简单的例子

假设我们有一个目录,其中包含许多不同类型的文件。我们想知道该目录中有多少种特定类型的文件。还有其他方法可以执行此操作,但是本练习的目的是引入管道,因此我们将使用管道进行此操作。

我们可以使用ls轻松获得文件列表:

ls

为了分离出感兴趣的文件类型,我们将使用grep。我们要查找文件名或者文件扩展名中包含单词页面的文件。

我们将使用shell特殊字符|ls的输出传递给grep

ls | grep "page"

grep打印符合其搜索模式的行。因此,这给了我们仅包含.page文件的列表。

即使这个简单的示例也显示了管道的功能。 ls的输出没有发送到终端窗口。它作为grep命令的数据发送到grep。我们看到的输出来自" grep",这是该链中的最后一条命令。

延伸我们的链条

让我们开始扩展管道命令链。我们可以通过添加wc命令来计算.page文件。我们将在wc中使用-l(行数)选项。注意,我们还向ls添加了-l(长格式)选项。我们将很快使用它。

ls - | grep "page" | wc -l

grep不再是链中的最后一个命令,因此我们看不到它的输出。 grep的输出被送入wc命令,我们在终端窗口中看到的输出来自wc。 wc报告目录中有69个.page文件。

让我们再扩展一遍。我们将从命令行中删除wc命令,并将其替换为awk。 ls输出中有9列带有-l(长格式)选项。我们将使用awk打印第五,第三和九列。这些是文件的大小,所有者和名称。

ls -l | grep "page" | awk '{print  " "  " " }'

我们为每个匹配文件获得了这些列的列表。

现在,我们将通过sort命令传递该输出。我们将使用-n(数字)选项来使sort知道应该将第一列视为数字。

ls -l | grep "page" | awk '{print  " "  " " }' | sort -n

现在,按照文件大小顺序对输出进行排序,我们定制了三列。

添加另一个命令

我们将通过添加tail命令来结束。我们将告诉它仅列出输出的最后五行。

ls -l | grep "page" | awk '{print  " "  " " }' | sort -n | tail -5

这意味着我们的命令将转换为类似的内容,显示此目录中五个最大的.page文件,按大小排序。当然,没有命令可以完成此任务,但是通过使用管道,我们创建了自己的管道。我们可以添加此命令或者任何其他长命令作为别名或者shell函数,以保存所有键入内容。

这是输出:

我们可以通过在sort命令中添加-r选项来反转大小顺序,并使用head而不是tail从输出的顶部拾取行。


这次从最大到最小列出了五个最大的.page文件:

最近的一些例子

这是最近的How-To怪胎文章中的两个有趣的示例。

一些命令,例如xargs命令,旨在将输入通过管道传递给它们。这是一种让wc计数多个文件中的单词,字符和行数的方法,方法是将ls传递到xargs中,然后将文件名列表馈送到wc,就像它们已经传递给wc一样命令行参数。

ls *.page | xargs wc

单词,字符和行的总数在终端窗口的底部列出。

这是一种获取当前目录中唯一文件扩展名的排序列表的方法,每种类型都有一个计数。

ls | rev | cut -d'.' -f1 | rev | sort | uniq -c

这里有很多事情。

  • ls:列出目录中的文件

  • rev:反转文件名中的文本。

  • cut:在第一次出现指定分隔符时剪切字符串。此之后的文本将被丢弃。

  • rev:反转剩余的文本,即文件扩展名。

  • sort:按字母顺序对列表进行排序。

  • uniq:计算列表中每个唯一条目的数量。

输出显示文件扩展名列表,并按字母顺序对每种唯一类型进行计数。

命名管道

我们还有另一种管道,称为命名管道。前面示例中的管道是由Shell在处理命令行时即时创建的。创建,使用并丢弃管道。它们是短暂的,不会留下任何痕迹。它们仅在使用它们的命令运行时存在。

命名管道在文件系统中显示为持久对象,因此我们可以使用ls看到它们。它们之所以具有持久性,是因为它们在重新启动计算机后仍能幸免,尽管那时它们中的所有未读数据都将被丢弃。

一次使用了很多命名管道,以允许不同的进程发送和接收数据,但是我很久没有看到它们使用这种方式了。毫无疑问,仍然有很多人在使用它们,从而发挥了巨大作用,但是我最近从未遇到过。但是为了完整起见,或者只是为了满足好奇心,这是如何使用它们的方法。

命名管道是使用mkfifo命令创建的。此命令将在当前目录中创建一个名为data-pipe的命名管道。

mkfifo data-pipe

如果我们使用带有-l(长格式)选项的ls命令,我们可以看到命名管道的详细信息:

ls -l data-pipe

列表的第一个字符是p,表示它是管道。如果是d,则表示文件系统对象是目录,而破折号-表示它是常规文件。

使用命名管道

让我们使用我们的管道。我们在前面的示例中使用的未命名管道将数据立即从发送命令传递到接收命令。通过命名管道发送的数据将保留在管道中,直到被读取。数据实际上是保存在内存中的,因此无论管道中是否有数据,命名管道的大小在ls列表中都不会改变。

在此示例中,我们将使用两个终端窗口。我将使用标签:

# Terminal-1

在一个终端窗口中

# Terminal-2

另外,我们可以区分它们。井号#告诉shell程序其后是注释,并忽略它。

让我们来看完整前面的示例,然后将其重定向到命名管道中。因此,我们在一个命令中同时使用了未命名管道和已命名管道:

ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > data-pipe

似乎什么都不会发生。我们可能会注意到,虽然我们没有返回到命令提示符,所以正在发生某些事情。

在另一个终端窗口中,发出以下命令:

cat < data-pipe

我们将命名管道的内容重定向到" cat"中,以便" cat"将在第二个终端窗口中显示该内容。这是输出:

并且我们会看到我们已经回到第一个终端窗口中的命令提示符。

所以,发生了什么。

  • 我们将一些输出重定向到命名管道。

  • 第一个终端窗口没有返回到命令提示符。

  • 数据保留在管道中,直到从第二个终端的管道中读取数据为止。

  • 我们回到了第一个终端窗口中的命令提示符。

我们可能会想,可以通过在命令的末尾添加一个"&"来在第一个终端窗口中将该命令作为后台任务运行。而且你会是对的。在这种情况下,我们将立即返回到命令提示符。

不使用后台处理的目的是要突出显示命名管道是一个阻塞过程。将东西放到命名管道中只会打开管道的一端。直到读取程序提取数据后,另一端才打开。内核将进程暂停在第一个终端窗口中,直到从管道的另一端读取数据为止。

管道的力量

如今,命名管道是一种新颖的行为。

另一方面,普通的老式Linux管道是我们可以在终端窗口工具箱中拥有的最有用的工具之一。 Linux命令行开始为我们启用,并且当我们可以编排一组命令以产生一个内聚的性能时,我们将获得全新的启动。

分步提示:最好编写一次管道命令,方法是一次添加一个命令并使该部分起作用,然后在下一个命令中进行管道传输。