Что происходит с исходной программой при передаче данных из одной программы в другую, если программа, получающая вывод, уничтожается?

Я передаю вывод программы наподобие этой, используя bash:

program1 | program2

Если program2 каким-то образом уничтожается (в моем случае фатальной ошибкой PHP), что происходит с экземпляром program1? 112]

1
задан 27 April 2011 в 16:04

4 ответа

Это очень зависит от того, что program1. Программное обеспечение должно быть в состоянии обрабатывать (или игнорировать) сигнал SIGPIPE. program1 будет нести ответственность за обработку ошибки - если программное обеспечение с открытым исходным кодом, вы сможете различить, что происходит, или если оно перехватывает / обнаруживает сигнал SIGPIPE. Если программное обеспечение ничего не делает с потоками, оно, скорее всего, завершит выполнение, прежде чем передать результаты. Я попытался показать небольшой пример, используя два сценария php.

program1

#!/usr/bin/env php
<?php

@unlink('program1.out');

for( $i = 0; $i < 10; $i++ )
{
    // This goes to either the buffer or whoever is next in the pipe
    echo $i . PHP_EOL;
    // Put everything in a file so we can see what Program1 actually did
    file_put_contents('program1.out', $i . PHP_EOL, FILE_APPEND);   
}

// All done! Cap off the file
file_put_contents('program1.out', 'Fin', FILE_APPEND);

program2

#!/usr/bin/env php
<?php

// We're taking inputs and just redirecting them to program2.out
// but to make it fun I'll throw an error half way through
// because I'm malicious like that

@unlink('program2.out');

$pipe_input = file("php://stdin");
$pipe_total = count($pipe_input);
$stop = rand(0, $pipe_total - 1);

echo "I'll be stopping at $stop" . PHP_EOL;

foreach( $pipe_input as $key => $input )
{
    if( $key == $stop )
    {
        file_put_contents('program2.out', 'Dead!', FILE_APPEND);
        die(1);
    }

    file_put_contents('program2.out', $input, FILE_APPEND);
}

Когда вы выполните ./program1 | ./program2, вы получите два файла .out по одному для каждой программы. В примере, который я запустил, я получил следующие файлы:

0
1
2
3
4
5
6
7
8
9
Fin

И для program2.out

0
1
2
3
4
Dead!

Первая программа будет выполнена и передаст ее содержимое второй. Вы заметите, что файл .out первой программы имеет полный набор чисел, а вторая содержит только набор, потому что он был уничтожен.

0
ответ дан 27 April 2011 в 16:04

Канал будет разорван, и программа, записывающая канал, получит сигнал SIGPIPE.

Из GLIBC :

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

0
ответ дан 27 April 2011 в 16:04

Краткий ответ: program1 умирает.

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

0
ответ дан 27 April 2011 в 16:04
[Нет 110] Ничего. Данные отправляются в / dev / null. Постскриптум О, да, программа получит сигнал, но это не значит, что ее придется закрыть.

0
ответ дан 27 April 2011 в 16:04

Другие вопросы по тегам:

Похожие вопросы: