作为评论,我很困惑为什么 makefile 中的“| true”与“|| true”用户cjm写道具有相同的效果:
另一个要避免的原因
| true
是,如果命令产生足够的输出来填满管道缓冲区,它将阻塞等待 true 读取它。
我们是否有办法找出管道缓冲区的大小?
Brian Kernighan 在此视频中解释了早期贝尔实验室对基于内存限制的小型语言/程序的吸引力
一台大机器将是 64 k 字节——K,而不是 M 或 G——这意味着任何单独的程序都不会很大,所以有一种自然的趋势,即编写小程序,然后是管道机制,基本上是输入输出重定向,可以将一个程序链接到另一个程序。
但考虑到数据必须存储在 RAM 中才能在程序之间传输,我不明白这如何限制内存使用。
来自维基百科:
在大多数类 Unix 系统中,一个管道的所有进程同时启动[强调我的],它们的流适当连接,并由调度程序与机器上运行的所有其他进程一起管理。将 Unix 管道与其他管道实现区分开来的一个重要方面是缓冲的概念:例如,发送程序每秒可能产生 5000 个字节,而接收程序每秒只能接受 100 个字节,但不能数据丢失。相反,发送程序的输出保存在缓冲区中。当接收程序准备好读取数据时,管道中的下一个程序从缓冲区读取。在 Linux 中,缓冲区的大小为 65536 字节 (64KB)。如果需要,可以使用名为 bfr 的开源第三方过滤器来提供更大的缓冲区。
这让我更加困惑,因为这完全违背了小程序的目的(尽管它们在一定程度上是模块化的)。
我唯一能想到的解决我的第一个问题(内存限制有问题取决于大小数据)的唯一方法是,当时根本没有计算大型数据集,而真正的问题管道是要解决的程序本身所需的内存量。但是鉴于维基百科引用中的粗体文本,即使这让我感到困惑:因为一次没有实施一个程序。
如果使用临时文件,所有这些都会很有意义,但我的理解是管道不会写入磁盘(除非使用交换)。
例子:
sed 'simplesubstitution' file | sort | uniq > file2
Run Code Online (Sandbox Code Playgroud)
我很清楚这sed
是读取文件并逐行吐出。但是sort
,正如 BK 在链接的视频中所说的那样,是一个句号,所以所有的数据都必须被读入内存(或者是吗?),然后它被传递给uniq
,这(在我看来)将是一个-一行一次的程序。但是在第一个和第二个管道之间,所有数据都必须在内存中,不是吗?
我只是在我的终端(Gnome 终端)上闲逛。我想知道有没有一种方法可以将一个终端的输出发送到另一个终端而无需创建新文件或管道。
例如:在第一个终端上我运行ls
并希望其输出显示在第二个终端上(在第二个终端上使用或不使用任何命令)
当我刚刚在 bash 中使用管道时,我没有考虑更多。但是当我阅读一些使用系统调用 pipe() 和 fork() 的 C 代码示例时,我想知道如何理解管道,包括匿名管道和命名管道。
经常听到“Linux/Unix 中的一切都是文件”。我想知道管道是否实际上是一个文件,以便它连接的一部分写入管道文件,另一部分从管道文件读取?如果是,创建的匿名管道的管道文件在哪里?在 /tmp、/dev 或 ...?
但是,从命名管道的例子中,我也了解到使用管道比显式使用临时文件具有空间和时间性能优势,可能是因为管道的实现不涉及文件。此外,管道似乎不像文件那样存储数据。所以我怀疑管道实际上是一个文件。