警告 Emptor:我不是 perl 向导。
正如@JonathanSwartz 建议的那样,我认为问题在于 apache2 mod_perl 关闭了 STDIN 和 STDOUT。这应该与 IPC::Open3 正在做的事情无关,但它有一个错误,在此处描述。
总而言之(这是我不太清楚的部分),open3 尝试将子进程 STDIN/OUT/ERR 与您的进程匹配,或者如果需要,则复制它。由于 open('>&=X') 工作的一些未记录方式,它通常工作正常,除非在 STDIN/OUT/ERR 关闭的情况下。
另一个深入了解细节的链接。
一种解决方案是修复 IPC::Open3,如这两个链接中所述。另一个对我有用的方法是在你的 mod_perl 代码中临时打开 STDIN/OUT,然后再关闭它:
my ($save_stdin,$save_stdout);
open $save_stdin, '>&STDIN';
open $save_stdout, '>&STDOUT';
open STDIN, '>&=0';
open STDOUT, '>&=1';
#make your normal IPC::Open3::open3 call here
close(STDIN);
close(STDOUT);
open STDIN, '>&', $save_stdin;
open STDOUT, '>&', $save_stdout;
另外,我注意到网上有很多关于 IPC::Run3 遇到同样问题的投诉,所以如果有人遇到同样的问题,我怀疑同样的解决方案会起作用。