管道如何影响标准输入?

管道如何影响标准输入?

我想写一个C程序,我需要解析stdin.如果我输入, fromcat file.txt | grep -v match如何解析 with ?它们是串联的吗?它们是两个不同的字符串吗?我跑了和,所以我在那里没有找到任何(看似)有用的东西。stdoutcat-v matchcat /dev/pts/0file /dev/pts/0

答案1

A管道是内核中分配的一个缓冲区,其中包含与读写端相关的文件描述符。当你跑步时cat file.txt | grep -v match

  • shell创建一个管道(使用pipe()系统调用)
  • 外壳fork()S.子进程使用dup2()系统调用来关闭其标准输出流并将管道的写入端复制到标准输出。 (此后,对标准输出的写入将进入内核缓冲区。)然后子进程exec()具有cat更新的标准输出。
  • 外壳fork()再次出现。子进程使用dup2()系统调用来关闭其标准输入流并将管道的读取端复制到标准输入。 (此后,从标准输入的读取将来自内核缓冲区。)然后子进程exec()具有grep更新的标准输入。

此时, 和 都cat正在grep运行。如果grep尝试从标准输入(管道)读取并且管道为空,则读取将阻塞。如果cat尝试写入标准输出(同样是管道)并且管道已满,则写入将被阻止。否则,当cat写入缓冲区时,grep可以从缓冲区读取。

答案2

C程序主函数的标准定义是

int main(int argc, char *argv[])

这里,argcargv是命令行参数,在本例中是-vmatchfor 。grep请注意,他们是不是单个字符串,但 shell 已经将参数分割为不同的字符串(NUL/\0终止,如 C 中常见)。argc包含参数数量以及argv参数本身。

另一方面,标准输入只是一个FILE *,您可以直接将它与任何stdio函数一起使用。fgets(buf, sizeof(buf), stdin)ETC。


我不知道你从哪里得到的cat /dev/pts/0。它将从特定的伪终端读取,可能与同一终端上的 shell 的读取发生冲突。 (尝试打开两个终端,xterm、SSH 会话、屏幕等等。然后tty在第一个终端上运行,它会显示终端的名称,例如/dev/pts/123cat /dev/pts/123在第二个终端中运行(使用给定的名称),然后尝试键入第一个的东西。)

相关内容