破管不再结束程序?

时间:2022-01-30 15:39:42

When you pipe two process and kill the one at the "output" of the pipe, the first process used to receive the "Broken Pipe" signal, which usually terminated it aswell. E.g. running

当您管道两个进程并在管道的“输出”处终止该进程时,第一个进程用于接收“Broken Pipe”信号,该信号通常也会终止它。例如。赛跑

$> do_something_intensive | less

and then exiting less used to return you immediately to a responsive shell, on a SuSE8 or former releases. when i'm trying that today, do_something_intensive is obviously still running until i kill it manually. It seems that something has changed (glib ? shell ?) that makes program ignore "broken pipes" ...

然后退出较少用于在SuSE8或以前的版本上立即返回到响应式shell。当我今天尝试时,do_something_intensive显然仍在运行,直到我手动杀死它。似乎某些事情发生了变化(glib?shell?),这使得程序忽略了“破碎的管道”......

Anyone of you has hints on this ? how to restore the former behaviour ? why it has been changed (or why it always existed multiple semantics) ?

你们中的任何人都有这方面的暗示吗?如何恢复以前的行为?为什么它已被改变(或为什么它总是存在多个语义)?

edit : further tests (using strace) reveal that "SIGPIPE" is generated, but that the program is not interrupted. A simple

编辑:进一步测试(使用strace)显示生成了“SIGPIPE”,但程序没有被中断。一个简单的

#include <stdio.h>
int main() 
{
   while(1) printf("dumb test\n");
   exit(0);
}

will go on with an endless

将继续无穷无尽

--- SIGPIPE (Broken pipe) @ 0 (0) ---
write(1, "dumb test\ndumb test\ndumb test\ndu"..., 1024) = -1 EPIPE (Broken pipe)

when less is killed. I could for sure program a signal handler in my program and ensure it terminates, but i'm more looking for some environment variable or a shell option that would force programs to terminate on SIGPIPE

少被杀的时候。我可以肯定在我的程序中编写一个信号处理程序并确保它终止,但我更需要一些环境变量或shell选项来强制程序在SIGPIPE上终止

edit again: it seems to be a tcsh-specific issue (bash handles it properly) and terminal-dependent (Eterm 0.9.4)

再次编辑:它似乎是一个特定于tcsh的问题(bash正确处理它)和终端依赖(Eterm 0.9.4)

3 个解决方案

#1


8  

Well, if there is an attempt to write to a pipe after the reader has gone away, a SIGPIPE signal gets generated. The application has the ability to catch this signal, but if it doesn't, the process is killed.

好吧,如果在读取器消失后尝试写入管道,则会生成SIGPIPE信号。应用程序能够捕获此信号,但如果没有,则该进程被终止。

The SIGPIPE won't be generated until the calling process attempts to write, so if there's no more output, it won't be generated.

在调用进程尝试写入之前不会生成SIGPIPE,因此如果没有更多输出,则不会生成它。

#2


2  

Has "do something intensive" changed at all?

“做一些密集的事情”有变化吗?

As Daniel has mentioned SIGPIPE is not a magic "your pipe went away" signal but rather a "nice try, you can no longer read/write that pipe" signal.

正如丹尼尔所说,SIGPIPE不是一个神奇的“你的管道消失”信号,而是一个“不错的尝试,你不能再读/写那个管道”信号。

If you have control of "do something intensive" you could change it to write out some "progress indicator" output as it spins. This would raise the SIGPIPE in a timely fashion.

如果您可以控制“做一些密集的事情”,您可以将其更改为在旋转时写出一些“进度指示器”输出。这将及时提升SIGPIPE。

#3


0  

Thanks for your advices, the solution is getting closer...

感谢您的建议,解决方案越来越近......

According to the manpage of tcsh, "non-login shells inherit the terminate behavior from their parents. Other signals have the values which the shell inherited from its parent."

根据tcsh的联机帮助页,“非登录shell继承父项的终止行为。其他信号具有shell从其父级继承的值。”

Which suggest my terminal is actually the root of the problem ... if it ignored SIGPIPE, the shell itself will ignore SIGPIPE as well ...

这表明我的终端实际上​​是问题的根源......如果忽略了SIGPIPE,shell本身也会忽略SIGPIPE ......

edit: i have the definitive confirmation that the problem only arise with Eterm+tcsh and found a suspiciously missing signal(SIGPIPE,SIG_DFL) in Eterm source code. I think that close the case.

编辑:我有确切的确认,问题只出现在Eterm + tcsh,并在Eterm源代码中发现了一个可疑的缺失信号(SIGPIPE,SIG_DFL)。我认为结案就好了。

#1


8  

Well, if there is an attempt to write to a pipe after the reader has gone away, a SIGPIPE signal gets generated. The application has the ability to catch this signal, but if it doesn't, the process is killed.

好吧,如果在读取器消失后尝试写入管道,则会生成SIGPIPE信号。应用程序能够捕获此信号,但如果没有,则该进程被终止。

The SIGPIPE won't be generated until the calling process attempts to write, so if there's no more output, it won't be generated.

在调用进程尝试写入之前不会生成SIGPIPE,因此如果没有更多输出,则不会生成它。

#2


2  

Has "do something intensive" changed at all?

“做一些密集的事情”有变化吗?

As Daniel has mentioned SIGPIPE is not a magic "your pipe went away" signal but rather a "nice try, you can no longer read/write that pipe" signal.

正如丹尼尔所说,SIGPIPE不是一个神奇的“你的管道消失”信号,而是一个“不错的尝试,你不能再读/写那个管道”信号。

If you have control of "do something intensive" you could change it to write out some "progress indicator" output as it spins. This would raise the SIGPIPE in a timely fashion.

如果您可以控制“做一些密集的事情”,您可以将其更改为在旋转时写出一些“进度指示器”输出。这将及时提升SIGPIPE。

#3


0  

Thanks for your advices, the solution is getting closer...

感谢您的建议,解决方案越来越近......

According to the manpage of tcsh, "non-login shells inherit the terminate behavior from their parents. Other signals have the values which the shell inherited from its parent."

根据tcsh的联机帮助页,“非登录shell继承父项的终止行为。其他信号具有shell从其父级继承的值。”

Which suggest my terminal is actually the root of the problem ... if it ignored SIGPIPE, the shell itself will ignore SIGPIPE as well ...

这表明我的终端实际上​​是问题的根源......如果忽略了SIGPIPE,shell本身也会忽略SIGPIPE ......

edit: i have the definitive confirmation that the problem only arise with Eterm+tcsh and found a suspiciously missing signal(SIGPIPE,SIG_DFL) in Eterm source code. I think that close the case.

编辑:我有确切的确认,问题只出现在Eterm + tcsh,并在Eterm源代码中发现了一个可疑的缺失信号(SIGPIPE,SIG_DFL)。我认为结案就好了。