Сломанная труба больше не завершает программы?

StackOverflow https://stackoverflow.com/questions/103016

  •  01-07-2019
  •  | 
  •  

Вопрос

Когда вы передаете два процесса по конвейеру и уничтожаете один на «выходе» канала, первый процесс обычно получает сигнал «Broken Pipe», который обычно также завершает его.Например.бег

$> do_something_intensive | less

а затем выход меньше используется для немедленного возврата к адаптивной оболочке на SuSE8 или более ранних версиях.когда я попробую это сегодня, сделать_что-то_интенсивное очевидно, все еще работает, пока я не остановлю его вручную.Кажется, что-то изменилось (glib?оболочки ?), что заставляет программу игнорировать "сломанные каналы"...

У кого-нибудь из вас есть подсказки по этому поводу?как вернуть прежнее поведение?почему оно было изменено (или почему всегда существовало несколько семантик)?

редактировать :дальнейшие тесты (с использованием 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)

когда меньше убит.Я мог бы наверняка запрограммировать обработчик сигнала в своей программе и обеспечить его завершение, но я больше ищу какую-нибудь переменную среды или опцию оболочки, которая заставит программы завершать работу на SIGPIPE.

редактировать еще раз:похоже, это проблема, специфичная для tcsh (bash обрабатывает ее правильно) и зависит от терминала (Eterm 0.9.4)

Это было полезно?

Решение 3

Спасибо за советы, решение все ближе...

Согласно man-странице tcsh, «оболочки без входа в систему наследуют поведение завершения от своих родителей.Другие сигналы имеют значения, которые оболочка унаследовала от своего родителя».

Что предполагает мой Терминал на самом деле корень проблемы...если он проигнорировал SIGPIPE, сама оболочка также проигнорирует SIGPIPE...

редактировать: У меня есть окончательное подтверждение того, что проблема возникает только с Eterm + tcsh, и я обнаружил подозрительно отсутствующий сигнал (SIGPIPE, SIG_DFL) в исходном коде Eterm.Думаю, что дело закрыто.

Другие советы

Что ж, если происходит попытка записи в канал после того, как считыватель ушел, генерируется сигнал SIGPIPE.Приложение имеет возможность перехватить этот сигнал, но если этого не происходит, процесс завершается.

SIGPIPE не будет сгенерирован до тех пор, пока вызывающий процесс не попытается выполнить запись, поэтому, если выходных данных больше нет, он не будет сгенерирован.

Изменилось ли вообще правило «делать что-нибудь интенсивное»?

Как упомянул Дэниел, SIGPIPE — это не волшебный сигнал «ваша трубка исчезла», а скорее сигнал «хорошая попытка, вы больше не можете читать/записывать эту трубку».

Если у вас есть контроль над «сделать что-то интенсивное», вы можете изменить его, чтобы записывать некоторый вывод «индикатора прогресса» во время его вращения.Это позволит своевременно поднять SIGPIPE.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top