2017-02-23 2 views
3

Cette impression 1..10 deux fois:Perl: laisser open3 hériteront STDIN, STDOUT, STDERR

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

Je voudrais faire la même chose en utilisant IPC :: Open3, mais je ne peux pas que travailler:

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 

Répondre

5

tout d'abord, la notation propre à hériter des poignées est:

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

Mais l'impression 1..10 deux fois? Vous ne devriez pas compter sur cela! Cela n'arrivera que si le timing est juste. En fait, cela arrive très rarement pour moi, même pour votre programme original. Les problèmes proviennent du fait que les processus parent et enfant partagent le même pointeur de fichier.

Peut-être que pour éviter que les utilisateurs ne se fient à ce comportement extrêmement peu fiable, open3 ferme le premier handle lorsqu'il s'agit d'un dup créé. Il est possible de le tromper comme suit:

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

De cette façon, open3 fermera la CHILD_STDIN dup, mais pas StdIn lui-même. Avec ce changement, vous obtiendrez la liste imprimée deux fois quand vous êtes chanceux.

+0

Le dupe est bien, mais je n'arrive toujours pas à lire le fichier deux fois. –

+2

Comme je l'ai déjà expliqué, ce que vous essayez de faire dépend du timing, ce qui signifie que cela n'arrivera que si le timing est juste. C'était le cas avec votre programme original aussi. Vous ne devriez vraiment pas faire ce que vous essayez de faire! Pour éviter le caractère aléatoire, j'ai remplacé 'fork();' par my mon pid = fork(); waitpid ($ pid, 0) si $ fork; 'lors du test. Cela assurait que l'un des processus (le parent) s'appelait seulement «chercher» après que l'autre (l'enfant) avait fini de lire et assurait ainsi la double impression. – ikegami