有人知道bash是如何通过管道发送数据的吗?
cat file.txt | tail -20此命令是否将file.txt的所有内容打印到缓冲区中,然后由尾读取?或者这个命令,例如,逐行打印file.txt的内容,然后在每一行暂停以进行尾处理,然后请求更多的数据?
我之所以问这个问题,是因为我在一个嵌入式设备上编写了一个程序,它基本上是对某个数据块执行一系列操作,其中一个操作的输出作为下一个操作的输入发送出去。我想知道linux (bash)是如何处理这一问题的,所以请给我一个一般性的答案,而不是具体地说,当我运行"cat file.txt维特-20“时会发生什么。
编辑: Shog9指出了维基百科的一篇相关文章,这并不能直接引导我找到这篇文章,但它帮助我找到了这个:%28Unix%29#Implementation,它有我想要的信息。
很抱歉我没说清楚。当然,您使用的是管道,当然,您使用的是命令各个部分的stdin和stdout。我曾认为这是显而易见的,不足以说明。
我要问的是这是如何处理/实现的。由于这两个程序都不能同时运行,那么如何将数据从stdin发送到stdout?如果第一个程序生成的数据比第二个程序要快得多,会发生什么?系统只是运行第一个命令,直到它被终止,或者它的stdout缓冲区已经满了,然后在循环中继续到下一个程序,等等,直到没有更多的数据需要处理,或者是否有一个更复杂的机制?
发布于 2008-08-21 05:46:23
我决定写一个稍微详细些的解释。
这里的“魔力”在于操作系统。这两个程序确实在大致相同的时间启动,并且在同一时间运行(操作系统为它们分配处理器上运行的时间片),就像计算机上每一个同时运行的进程(包括终端应用程序和内核)一样。因此,在传递任何数据之前,进程都在进行任何必要的初始化。在您的示例中,尾巴解析'-20‘参数,cat解析'file.txt’参数并打开文件。在某个时候,尾巴会到达它需要输入的位置,它会告诉操作系统它正在等待输入。在另一个点(无论是在之前还是之后,这都无关紧要),cat将开始使用stdout将数据传递到操作系统。这将进入操作系统中的缓冲区。下一次,当某些数据被cat放入缓冲区后,尾巴将在处理器上获得一个时间片,它将检索一定数量的数据(或全部数据),从而将缓冲区留在操作系统上。当缓冲区为空时,尾部将不得不等待cat输出更多数据。如果cat输出数据的速度远远快于尾巴处理数据的速度,缓冲区就会扩展。cat最终将完成输出数据,但是尾巴仍将被处理,因此cat将关闭并在缓冲区中处理所有剩余的数据。当它们不再是EOF输入的数据时,操作系统就会发出尾部信号。尾巴将处理剩余的数据。在这种情况下,尾巴可能只是将所有数据接收到一个20行的循环缓冲区中,当操作系统指示它没有更多的传入数据时,它会将最后20行转储到自己的stdout中,然后在终端中显示。因为tail是一个比cat简单得多的程序,它可能会花费大部分时间等待cat将数据放入缓冲区。
在一个具有多个处理器的系统上,这两个程序不仅在同一个处理器核上共享交替的时间片,而且很可能在不同的核上同时运行。
为了更详细地介绍一下,如果您在Linux中打开某种进程监视器(特定于操作系统),比如“top”,您将看到一个完整的正在运行的进程列表,其中大多数进程有效地使用了0%的处理器。大多数应用程序,除非它们正在处理数据,否则大部分时间都不做任何事情。这很好,因为它允许其他进程根据它们的需要不受限制地访问处理器。这主要通过三种方式来完成。一个进程可以进入睡眠(N)风格的指令,它基本上告诉内核等待n毫秒,然后再给它另一个处理时间片。最常见的情况是,一个程序需要等待来自另一个程序的东西,比如“尾巴”,等待更多的数据进入缓冲区。在这种情况下,当有更多数据可用时,操作系统将唤醒进程。最后,内核可以在执行过程中抢占一个进程,给其他进程一些处理器时间片。“猫”和“尾巴”是简单的程序。在本例中,tail花费了大部分时间在缓冲区上等待更多数据,而cat则花费了大部分时间等待操作系统从硬盘中检索数据。瓶颈是存储文件的物理介质的速度(或慢度)。当您第一次运行此命令时,您可能会检测到的延迟是磁盘驱动器上的读头查找到硬盘上“file.txt”所在位置所需的时间。如果第二次运行该命令,操作系统可能会在内存中缓存file.txt的内容,并且您可能不会看到任何明显的延迟(除非file.txt非常大,或者文件不再缓存)。
您在计算机上执行的大多数操作都是IO绑定的,也就是说,您通常在等待来自硬盘或网络设备的数据。
发布于 2008-08-21 01:45:20
Shog9已经引用了维基百科的文章,但是执行部分有你想要的细节。基本实现是一个有界的缓冲区。
发布于 2008-08-21 00:29:00
cat只会将数据打印到标准输出,这恰好被重定向到标准的尾部。这可以在bash的手册页中看到。
换句话说,没有停顿,尾巴只是从标准读物,而猫只是写出来的标准。
https://stackoverflow.com/questions/19122
复制相似问题