3

这打印 1..10 两次:

seq 10 > /tmp/ten
perl -e 'fork();seek(STDIN,0,0); print <STDIN>' </tmp/ten

我想使用 IPC::Open3 做同样的事情,但我无法让它工作:

perl -MIPC::Open3 -e 'fork();seek(STDIN,0,0); open3(0,1,2,"cat");' < /tmp/ten
perl -MIPC::Open3 -e 'fork();seek(STDIN,0,0); open3(STDIN,STDOUT,STDERR,"cat");' < /tmp/ten
perl -MIPC::Open3 -e 'fork();seek(STDIN,0,0); open3(*STDIN,*STDOUT,*STDERR,"cat");' < /tmp/ten
perl -MIPC::Open3 -e 'fork();seek(STDIN,0,0); open3(\*STDIN,\*STDOUT,\*STDERR,"cat");' < /tmp/ten
4

1 回答 1

5

首先,继承句柄的正确表示法是:

open3("<&STDIN", ">&STDOUT", ">&STDERR", "cat")

但是打印 1..10 两次?你不应该依赖这种情况发生!只有时机恰到好处,它才会发生。事实上,这对我来说很少发生,即使是你的原始程序也是如此。问题源于父进程和子进程共享相同的文件指针这一事实。

也许为了避免让人们依赖这种极其不可靠的行为,open3当它是它创建的副本时关闭第一个句柄。可以按如下方式欺骗它:

open(local *CHILD_STDIN, "<&", \*STDIN) or die $!;
open3("<&CHILD_STDIN", ">&STDOUT", ">&STDERR", "cat")

这样,open3将关闭 dup CHILD_STDIN,但不会关闭 STDIN 本身。通过此更改,您将在幸运时将列表打印两次。

于 2017-02-24T00:02:06.667 回答