linux / unix系统中管道运算符/管道字符(竖线字符“ |”)的可执行文件是什么

时间:2018-09-10 02:39:27

标签: linux shell unix syntax

通常,我们在Linux系统的terminal / tty / command窗口中运行命令。 如果运行ls -l,我们就会知道实际上执行了一个位于ls的名为/bin的文件。完整路径为/bin/ls

关于* nix类系统中的管道有很多讨论。与|相对应的系统中确切的可执行文件是什么?即使管道功能内置在系统中,也应该找到一段代码。我找不到有关的文档。从Google的结果页中挑选答案并非易事。

我已经阅读了一些有关管道创建的基本信息,或者有关使用C语言进行管道编程的内容。这些看上去与|的行为截然不同。外壳程序中的管道运算符(“ |”)是否与基本C编程书籍中描述的示例相同?

除了|,竖线字符之外,><的对应文件是什么?

更新1: 从下面的帖子中得到一些答案之后,我认为我的管道机制的原始骨架被称为http://www.linfo.org/pipe.html

的“假管道”

4 个答案:

答案 0 :(得分:5)

您所指的字符是 shell运算符,而不是可执行文件 (例如,二进制文件,例如/bin/ls ,又名外部实用程序)。

也就是说,这些字符指示Shell如何协调执行 命令(外部实用程序,shell内置函数,函数,别名),并重定向其输入/输出

  • |是外壳 control运算符 的实例,它在pipeline中链接多个命令的执行。

  • <>是shell 重定向操作符 ,用于重定向 stdin 输入和 stdout 输出。

如果您的外壳是bash,请咨询man bash,或更普遍的是,man $SHELL

答案 1 :(得分:4)

没有|<的文件。这些是在外壳内部实现的。 ifforwhileetc也是如此。它无法实现为可执行文件,因为|连接了可执行文件,指示外壳程序对其输入和输出应采取的措施。

答案 2 :(得分:4)

字符<>>>|ls之类的可执行文件的含义不同。相反,它们是对shell的指令,它们会修改其他进程的创建方式。

首先,请注意,尽管您键入Linux命令,但实际上并没有直接与Linux操作系统本身进行交互。您正在使用一个称为Shell的程序-很可能是/bin/bash,但是有几种可用的Shell程序,其中大多数以基本相同的方式运行。 Shell的主要目的是解释您的输入,以便启动其他进程。这涉及到Linux系统调用fork(或者可能是clone)来创建一个新的过程作为shell进程的子进程,然后是系统调用execve来加载该子进程并使用指定的参数运行指定的程序。

shell可能会对输入进行各种解释,以确定实际的程序和参数将是什么,例如替换命令别名,替换环境变量以及扩展~*和{ {1}}个字符。同样,[]<>>>符号对shell具有特殊的含义,但它们没有修改可执行文件的名称或参数,而是精确地修改了如何子进程已创建。

Linux进程通常以打开的三个“文件句柄”开始:标准输入,标准输出和标准错误。默认情况下,shell的子进程将使用与shell相同的输入/输出/错误,这意味着它们可以通过与shell相同的机制从键盘获取输入,并且进程的输出出现在同一窗口中。当使用|<>重定向指令时,外壳程序将在>>fork之间修改进程的文件句柄。因此,即使在子文件中启动可执行文件之前,它的一个或多个默认文件句柄实际上都会从命名文件中读取/写入。

使用“管道”字符execve时,外壳程序将大约同时启动两个子进程,但第一个进程的输出将连接到第二个进程的输入。这涉及系统调用pipe,以创建一对文件句柄,在其中写入一个句柄只会将数据放入操作系统内存中,直到从另一个句柄中读取该数据为止。

例如,

|

将(不一定按此顺序):

  1. 创建一对管道文件句柄
  2. grep 'MAGIC' file1.txt | sort 命令创建一个子进程。
  3. 替换子级的标准输出文件句柄以使用管道的写端。
  4. 通过grep开始grep命令。
  5. execve命令创建一个子进程。
  6. 替换子级的标准输入文件句柄以使用管道的读取端。
  7. 通过sort开始sort命令。
  8. 等待execve子进程完成。

就“即使在系统中构建了管道功能,也应该找到一段代码”而言,您会在Shell程序的代码中找到用于解释这些特殊Shell字符的代码。

答案 3 :(得分:3)

管道不是可执行文件,而是一种拥有inter-process communication(在pipelines中)的方法。它是Linux kernel提供的一项基本功能(与许多其他功能一样,包括文件,目录和进程)。相关的system callpipe(2),而pipe(7)页面提供了更多说明。

至少需要一本完整的书来回答您的问题。所以我们不能在这里回答。但我提供了一些参考:

阅读有关Linux编程的书,例如旧的ALP书(可免费下载;它包含与您的问题相关的几章)或更新的书。另请参见syscalls(2)的列表。

然后阅读一些有关操作系统的书。我推荐Operating Systems: Three Easy Pieces(可免费下载;它又有几章与您的问题有关)。

因此,您需要花几天或几周的时间阅读。

您的外壳程序正在使用pipe(2)来解释|。对于redirections,例如><,它使用dup2(2)dup。当然,shell使用fork(2)创建进程,使用waitpid(2)或类似的进程等待它们,并使用execve(2)运行程序。 Globbing(请参阅glob(7))要求使用opendir(3)readdir(3)等扫描目录,并使用stat(2) ... cd查询文件元数据内置的shell,并使用chdir(2)

因此,您还需要阅读有关unix shells的更多信息(了解它们的一个好方法是用C编写自己的小外壳;这是一个非常常见且有趣的练习)。

顺便说一句,大多数Unix外壳都是free software。您可以研究他们的源代码。 sash外壳程序有点bug,但是它很小(非常基础!),并且其源代码可读性强。当然,诸如bashzshfish之类的实际实用shell具有更多功能(其中大多数是为了方便起见),因此更加复杂,但是您仍然可以研究其源代码,因为它们是免费软件。