一切都是文件。

一切都是文件。

当我刚刚在bash中使用管道时,我并没有更多地考虑这一点。但是当我阅读一些使用系统调用 pipeline() 和 fork() 的 C 代码示例时,我想知道如何理解管道,包括匿名管道和命名管道。

人们经常听说“Linux/Unix 中的一切都是文件”。我想知道管道是否实际上是一个文件,以便它连接的一部分写入管道文件,另一部分从管道文件读取?如果是,则在哪里创建匿名管道的管道文件?在/tmp、/dev 或...?

然而,从命名管道的例子中,我还了解到,使用管道比显式使用临时文件具有空间和时间性能优势,可能是因为管道的实现不涉及文件。而且管道似乎不像文件那样存储数据。所以我怀疑管道实际上是一个文件。

答案1

关于您的性能问题,管道比文件更有效,因为不需要磁盘 IO。因此cmd1 | cmd2比(如果作为命名管道支持在 RAM 磁盘或其他内存设备上,则cmd1 > tmpfile; cmd2 < tmpfile这可能不成立;但如果它是命名管道,则应在后台运行,因为如果管道已满,其输出可能会阻塞) )。如果您需要 的结果并且仍然需要将其输出发送到,您应该允许和并行运行,避免从 进行磁盘读取操作。tmpfilecmd1cmd1cmd2cmd1 | tee tmpfile | cmd2cmd1cmd2cmd2

如果许多进程读/写同一管道,则命名管道非常有用。当程序未设计为使用 stdin/stdout 来进行需要使用的 IO 时,它们也很有用文件。我将文件用斜体表示,因为从存储的角度来看,命名管道并不完全是文件,因为它们驻留在内存中并且具有固定的缓冲区大小,即使它们具有文件系统条目(仅供参考)。其他事物在 UNIX 中,有文件系统条目而不是文件:只需考虑或/dev/null中的其他条目。/dev/proc

由于管道(命名和未命名)具有固定的缓冲区大小,因此对它们的读/写操作可能会阻塞,导致读/写过程进入 IOWait 状态。另外,从内存缓冲区读取时什么时候收到 EOF ?关于这种行为的规则有明确的定义,可以在男人身上找到。

使用管道(命名和未命名)不能做的一件事是在数据中查找。由于它们是使用内存缓冲区实现的,这是可以理解的。

关于"everything in Linux/Unix is a file",我不同意。命名管道具有文件系统条目,但不完全是文件。无名管道没有文件系统条目(除了 in /proc)。然而,UNIX 上的大多数 IO 操作都是使用读/写函数完成的,需要一个文件描述符,包括未命名管道(和套接字)。我不认为我们可以这么说"everything in Linux/Unix is a file",但我们肯定可以这么说"most IO in Linux/Unix is done using a file descriptor"

答案2

UNIX 哲学的两个基本原理是

  1. 制作能够做好一件事的小程序。
  2. 并期望每个程序的输出成为另一个
    未知程序的输入。

    使用管道可以让您利用这两个设计
    基础的效果来创建极其强大的命令链来实现您想要的结果。

    大多数操作文件的命令行程序也可以接受标准输入(通过键盘输入)的输入并输出到标准输出(在
    屏幕上打印)。

    有些命令被设计为只能在管道内操作,不能直接对文件进行操作。

    例如tr命令

  ls -C | tr 'a-z' 'A-Z'
    cmd1 | cmd2
  • 将 cmd1 的 STDOUT 发送到 cmd2 的 STDIN,而不是屏幕。

  • STDERR 不通过管道转发。

    总之Pipes is character (|)可以连接命令。

    任何写入 STDOUT 的命令都可以在管道的左侧使用。

       ls - /etc | less 
    

    从 STDIN 读取的任何命令都可以在管道的右侧使用。

       echo "test print" | lpr 
    

    传统管道是“未命名的”,因为它匿名存在并且仅在进程运行时持续存在。命名管道是系统持久性的,并且在进程的生命周期之外存在,一旦不再使用就必须将其删除。进程通常附加到命名管道(通常显示为文件)以执行进程间通信(IPC)。

来源 :http://en.wikipedia.org/wiki/Named_pipe

答案3

为了补充其他答案...

stdin 和 stdout 是文件描述符,可以像文件一样进行读写。因此你可以这样做echo hi | grep hi,它将用管道替换 echo 的标准输出,并将 grep 的标准输入替换到该管道的另一端。

答案4

一切都是文件。

如果我们过于字面地理解这句话,我们最终会得到“我们只有文件,没有其他东西”的意思。这不是正确的解释,那又是什么。

当我们说“一切都是文件”时,我们并不是说一切都存储在磁盘上。我们说一切看起来都像一个文件,可以读取,可以写入。

在 Unix 中,一旦打开文件或非文件,就可以将其视为文件。然而,并非所有文件都支持所有操作。例如,某些文件(不是文件)不支持查找:它们必须按顺序读/写(管道和套接字也是如此)。

所有东西都有一个文件名(在某些系统上:例如 Debian Gnu/Linux 和许多其他 Gnu/Linux)。

  • 所有打开的文件都有一个文件名。看/proc/self/fd/…
  • 可以使用文件名打开网络套接字,请参见/dev/tcp
    例如cat </dev/tcp/towel.blinkenlights.nl/23

相关内容