这涉及系统编程,因此它不仅仅是一个基本问题。如所写,您的主程序不需要与外部程序进行全双工交互。数据流向一个方向传播,即
字符串→外部程序→主程序
创建此管道很简单。Perlopen
有一个有用的模式,在 perlipc 文档的“安全管道打开”部分中进行了说明。
进程间通信的另一种有趣方法是让您的单个程序成为多进程并在您自己之间甚至彼此之间进行通信。该open
函数将接受一个文件参数,或者"-|"
做"|-"
一件非常有趣的事情:它派生一个连接到您打开的文件句柄的孩子。孩子正在运行与父母相同的程序。例如,这对于在假定的 UID 或 GID 下运行时安全打开文件很有用。如果您打开一个减号管道,您可以写入您打开的文件句柄,您的孩子会在他的STDIN
. 如果你从减号打开一个管道,你可以从你打开的文件句柄中读取你的孩子写给他的任何内容STDOUT
。
这是一个open
涉及管道的管道,它为返回值提供了细微差别。perlfunc 文档open
解释了。
如果你在命令上打开一个管道-
(即,指定一个|-
或-|
两个参数形式open
),一个隐式fork
完成,所以 open 返回两次:在父进程中它返回子进程的 pid,并在子进程中返回 (a defined) 0
。使用defined($pid)
或//
确定是否open
成功。
为了创建脚手架,我们按照从右到左的顺序在每个步骤中使用open
新fork
流程。
- 您的主程序已经在运行。
- 接下来,
fork
一个最终将成为外部程序的进程。
- 在步骤 2 的过程中
- 首先
fork
是字符串打印过程,以使其输出到达我们的STDIN
.
- 然后
exec
外部程序执行其转换。
- 让字符串打印机完成它的工作,然后
exit
,它会进入下一个级别。
- 回到主程序,读取转换后的结果。
完成所有这些设置后,您所要做的就是将您的建议植入底部,科布先生。
#! /usr/bin/env perl
use 5.10.0; # for defined-or and given/when
use strict;
use warnings;
my @transform = qw( tr [A-Za-z] [N-ZA-Mn-za-m] ); # rot13
my @inception = (
"V xabj, Qnq. Lbh jrer qvfnccbvagrq gung V pbhyqa'g or lbh.",
"V jnf qvfnccbvagrq gung lbh gevrq.",
);
sub snow_fortress { print map "$_\n", @inception }
sub hotel {
given (open(STDIN, "-|") // die "$0: fork: $!") { # / StackOverflow hiliter
snow_fortress when 0;
exec @transform or die "$0: exec: $!";
}
}
given (open(my $fh, "-|") // die "$0: fork: $!") {
hotel when 0;
print while <$fh>;
close $fh or warn "$0: close: $!";
}
感谢有机会写出这么有趣的程序!