破损的管道不再终止程序?

发布于 2024-07-06 05:52:50 字数 893 浏览 9 评论 0原文

当您通过管道传输两个进程并在管道的“输出”处终止一个进程时,第一个进程用于接收“损坏的管道”信号,该信号通常也会终止它。 例如,在 SuSE8 或以前的版本上,运行

$> do_something_intensive | less

然后退出 less 用于立即返回到响应式 shell。 当我今天尝试时,do_something_intense 显然仍在运行,直到我手动终止它。 似乎有些东西发生了变化(glib?shell?),使程序忽略“损坏的管道”......

你们中的任何人对此有提示吗? 如何恢复以前的行为? 为什么它被改变了(或者为什么它总是存在多种语义)?

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

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

将会继续下去

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

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

再次编辑:看起来是一个特定于 tcsh 的问题(bash 可以正确处理它)并且依赖于终端(Eterm 0.9.4)

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

gt; 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" ...

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

#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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

勿忘心安 2024-07-13 05:52:50

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

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

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

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.

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.

猫烠⑼条掵仅有一顆心 2024-07-13 05:52:50

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

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

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

编辑:我有明确的答案确认该问题仅在 Eterm+tcsh 中出现,并在 Eterm 源代码中发现可疑的缺失信号(SIGPIPE、SIG_DFL)。 我认为结案了。

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."

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

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.

番薯 2024-07-13 05:52:50

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

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

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文