无壳(但可能不太便携)版本:
#!perl
use strict;
use warnings;
use Fcntl;
open my $one, '-|', 'echo', 'string1' or die "$! opening first input";
fcntl $one, F_SETFD, (fcntl($one, F_GETFD, 0) & ~FD_CLOEXEC)
or die "$! keeping open first input";
open my $two, '-|', 'echo', 'string2' or die "$! opening second input";
fcntl $two, F_SETFD, (fcntl($two, F_GETFD, 0) & ~FD_CLOEXEC)
or die "$! keeping open second input";
open my $diff, '-|', 'diff', "/dev/fd/".fileno($one), "/dev/fd/".fileno($two)
or die "$! running diff";
while (<$diff>) {
print;
}
这基本上正是shell所做的(为第一个“echo”命令打开一个子进程,为第二个“echo”命令打开一个子进程,允许子进程继承它们的文件句柄,然后打开一个子进程到“diff”命令,其参数是指向打开的文件句柄的特殊文件名)。唯一的区别是,我们不是让 diff 打印到屏幕上,而是捕获输出并自己打印——因为我认为您可能想要对输出做一些事情而不仅仅是查看它。
新版本(无/bin/echo,无转义,无死锁)
#!/usr/bin/perl
use strict;
use warnings;
use Fcntl;
my $pid_one = open my $one, '-|';
die "$! opening first input" unless defined $pid_one;
if (!$pid_one) { # child
print "string1\n";
exit;
}
fcntl $one, F_SETFD, (fcntl($one, F_GETFD, 0) & ~FD_CLOEXEC)
or die "$! keeping open first input";
my $pid_two = open my $two, '-|';
die "$! opening second input" unless defined $pid_two;
if (!$pid_two) { # child
print "string2\n";
exit;
}
fcntl $two, F_SETFD, (fcntl($one, F_GETFD, 0) & ~FD_CLOEXEC)
or die "$! keeping open second input";
open my $diff, '-|', 'diff', "/dev/fd/".fileno($one), "/dev/fd/".fileno($two)
or die "$! running diff";
while (<$diff>) {
print;
}
string1
并且string2
可以是任何东西,包括来自父进程的变量或其他命令的输出。