#!/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);
程序2
#!/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
。软件需要能够处理(或忽略)SIGPIPE
信号。program1
将负责处理错误 - 如果软件是开源的,您应该能够辨别发生了什么或者它是否捕获/检测到SIGPIPE
信号。如果软件没有对流做任何特殊处理,它可能会在传递结果之前完成执行。我尝试了一个小例子来使用两个 php 脚本来说明这一点。程序1
程序2
当您执行时,
./program1 | ./program2
您将获得两个.out
文件,每个文件一个。在我运行的示例中,我得到了以下文件:而对于
program2.out
第一个程序将执行并将其内容传递给第二个程序。您会注意到第一个程序的 .out 文件有一组完整的数字,而第二个程序只包含一组数字,因为它被杀死了。
管道将被破坏,写入管道的程序将收到 SIGPIPE 信号。
来自GLIBC:
没有什么。数据进入 /dev/null。PS哦,是的,程序会收到信号,但这并不意味着它必须关闭。
简短的回答是
program1
死亡。program1
SIGPIPE
管道破裂时收到信号。设计为长时间运行的守护程序的程序通常会处理信号并进行适当的清理,但典型的交互式程序不会。默认操作是终止程序,因此在大多数情况下,program1
只会被终止。