在这种情况下很少见到“破损的管道”,但这很正常。
当您运行时type rvm | head -1
,bash type rvm
在一个进程head -1
中执行,在另一个进程中执行。1的标准输出type
连接到管道的“写入”端,的标准输入head
连接到“读取”端。这两个过程同时运行。
该head -1
过程从stdin读取数据(通常以8 kB为块),打印出一行(根据-1
选项),然后退出,从而导致管道的“读取”端关闭。由于该rvm
功能相当长(由bash解析和重建后约为11 kB),因此这意味着head
退出时type
仍需要写入几kB的数据。
此时,由于type
试图写入另一端已关闭的管道(损坏的管道),因此它校准的write()函数将返回EPIPE错误,翻译为“损坏的管道”。除了此错误外,内核还将SIGPIPE信号发送给type
,默认情况下,该信号立即终止进程。
(该信号在交互式Shell中非常有用,因为大多数用户不希望第一个进程继续运行并试图写到任何地方。同时,非交互式服务会忽略SIGPIPE –对于长时间运行的守护程序而言,这样做不利。死于如此简单的错误-因此他们发现错误代码非常有用。)
但是,信号传递不是立即100%进行的,在某些情况下,write()返回EPIPE,并且该过程在接收到信号之前会继续运行一会儿。在这种情况下,type
在被SIGPIPE杀死之前,有足够的时间来注意到写入失败,翻译错误代码甚至将错误消息打印到stderr。(错误消息显示为“ -bash:类型:”,因为它type
是bash本身的内置命令。)
这在多CPU系统上似乎更常见,因为type
进程和内核的信号传递代码实际上可以同时在不同的内核上运行。
可以通过修补type
内置消息(在bash的源代码中)以在收到来自write()函数的EPIPE时立即退出的消息来删除此消息。
但是,没有什么可担心的,它与您的rvm
安装没有任何关系。