Я передаю вывод программы наподобие этой, используя bash:
program1 | program2
Если program2 каким-то образом уничтожается (в моем случае фатальной ошибкой PHP), что происходит с экземпляром program1? 112]
Это очень зависит от того, что program1
. Программное обеспечение должно быть в состоянии обрабатывать (или игнорировать) сигнал SIGPIPE
. program1
будет нести ответственность за обработку ошибки - если программное обеспечение с открытым исходным кодом, вы сможете различить, что происходит, или если оно перехватывает / обнаруживает сигнал SIGPIPE
. Если программное обеспечение ничего не делает с потоками, оно, скорее всего, завершит выполнение, прежде чем передать результаты. Я попытался показать небольшой пример, используя два сценария php.
#!/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);
#!/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 первой программы имеет полный набор чисел, а вторая содержит только набор, потому что он был уничтожен.
Канал будет разорван, и программа, записывающая канал, получит сигнал SIGPIPE.
Из GLIBC :
SIGPIPE Разбитая труба. Если вы используете каналы или FIFO, вы должны спроектировать свое приложение так, чтобы один процесс открыл канал для чтения, прежде чем другой начнет писать. Если процесс чтения никогда не начинается, или неожиданно завершается , запись в канал или FIFO вызывает сигнал SIGPIPE. Если SIGPIPE заблокирован, обработан или проигнорирован, вызывающий сбой вызов завершится неудачно с помощью EPIPE.
BLOCKQUOTE>
Краткий ответ: program1
умирает.
program1
получает сигнал SIGPIPE
, когда труба сломана. Программы, разработанные для долго работающих демонов, обычно обрабатывают сигнал и выполняют надлежащую очистку, но ваша типичная интерактивная программа - нет. Действие по умолчанию - завершить программу, поэтому по большей части program1
будет просто завершено.