重击内置定义作为:
shell直接执行命令,而不调用其他程序。
像这样的管道的foo | bar
工作原理大致如下:bar
等待来自 的输入foo
,然后foo
先退出,然后bar
退出。
在 bash 中,这样的管道按预期工作:
$ history | grep curl
但如何才能grep
知道history
它的工作已经完成并自行退出呢?由于history
是内置进程,因此不会产生新进程。会history
产生EOF
信号什么的吗?
答案1
当手册中说“不调用其他程序”时,这意味着 shell 不用于execve
执行其他程序。当命令使用重定向时,简单的实现是到fork
另一个进程并仅对该进程进行重定向,而不修改父 shell 的文件描述符。这也是bash
此命令的作用,可以通过 进行验证strace
。
可以采取一些技巧来避免内部命令的分叉,但在这种情况下似乎没有使用它们。
第二个程序无法检测到第一个程序退出,它只能检测到管道的输出端已关闭(这可能是因为程序退出,或者因为常规close
)。管道的读取端将收到 EOF。
管道中第一个程序先退出是常见情况,但并非必要。考虑一下:
sleep 10 | echo done
如果管道的第二个程序在第一个程序之前退出,并且第一个程序尝试写入管道,它将收到 signal SIGPIPE
,这将终止进程,除非它被捕获。
(sleep 10; echo test ) | echo done