我想写一个C程序,我需要解析stdin
.如果我输入, fromcat file.txt | grep -v match
如何解析 with ?它们是串联的吗?它们是两个不同的字符串吗?我跑了和,所以我在那里没有找到任何(看似)有用的东西。stdout
cat
-v match
cat /dev/pts/0
file /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[])
这里,argc
和argv
是命令行参数,在本例中是-v
和match
for 。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/123
。cat /dev/pts/123
在第二个终端中运行(使用给定的名称),然后尝试键入第一个的东西。)