你的程序,在这种情况下mydiff
,和(无论您选择为core.pager
less
,或)寻呼机通过连接管。操作系统在读取器必须清理一些内容之前可以写入管道的数据量有一定限制,并且寻呼机在暂停之前不会读取整个管道,因此在某些输出量时,管道已经填满并且您的程序在其系统调用write
中被阻止。
如果管道的读端消失(由具有寻呼机退出),两件事情发生在这一点上:操作系统提供了一个SIGPIPE
信号到你的程序,操作系统有write
系统调用失败,并EPIPE
错误。通常情况下,第一个信号会在第二个信号发生之前杀死你的程序,但是如果你的程序要赶上或者忽略SIGPIPE
,那么第二个就会发生。
下面是在SIGPIPE
一个作业控制壳杀死的处理的例子:
> cat book.pdf | : &
>
[1] Broken pipe cat book.pdf |
Done :
(顺便:
这里内置的结肠命令,这是一个空操作,它是一个剩从,我。想,Mashey外壳,有goto
作为一个外部程序)运行此作为一个经常前台进程,顺序是沉默:
> cat book.pdf | :
>
这是因为shell不埋怨死了,OF- SIGPIPE
过程中,自“死于SIGPIPE
”是很正常的。
无论出于何种原因,git
的前端对于这个死于SIGPIPE
的案件而言更为嘈杂。如果您不使用exec
,那么壳看到的是SIGPIPE
。贝壳静静地吸收并干净地离开,git不会抱怨。如果您使用做使用exec
,则shell将被替换为您的程序,并且git
前端命令将看到SIGPIPE
处于死亡状态并发出抱怨。
一个显而易见的治疗方法是将壳体留下。另一种方法是让壳忽略(抓不住)SIGPIPE
,然后做exec
:
trap "" PIPE
正如你noted in a comment-reply,捕SIGPIPE
没有很好:因为exec
替换地址的现任主人空间,操作系统重置所有将信号捕获到它们的默认配置(对于SIGPIPE
是“信号死亡”)。但是,忽略信号仍然被忽略。
根据您的程序,这可能是坏的或更糟的。例如,当SIGPIPE
cat
模具外壳是无声的,但是当cat
看到write
失败,EPIPE
它抱怨:
$ cat book.pdf | :
$ trap "" PIPE
$ cat book.pdf | :
cat: stdout: Broken pipe
(这是FreeBSD上;不同的操作系统略有不同,这取决于它们如何小心和聪明的实用工具是)。
一种可能性是忽略SIGPIPE像http://stackoverflow.com/a/22464942/5781248 –
@ J.J.Hakala我试过了,但它似乎没有工作。因为'exec'完全替换了当前正在运行的程序,所以我不认为信号陷阱是继承的。这在这里讨论:http://stackoverflow.com/questions/24111981/how-can-i-achieve-bash-exit-trap-when-exec-ing-another-binary – redtree