2010-10-03 21 views
0

Utilisation de proc_open() PHP, je peux démarrer un processus, lu à partir de STDOUT et STDERR (séparément) un nombre quelconque d'octets à la fois à l'aide de fread() pendant que le processus est en cours, détecter le moment où le processus est réalisé en utilisant feof() sur les STDOUT et STDERR tuyaux , puis utilisez proc_close() pour obtenir le code de sortie du processus. J'ai fait tout cela en PHP. Cela fonctionne bien, et me donne beaucoup de contrôle.Quel est l'équivalent Perl de proc_open() de PHP, proc_close(), etc.?

Existe-t-il un moyen de faire tout cela en Perl? Pour résumer, je dois être en mesure de faire ce qui suit:

  • commencer un processus externe
  • lire STDOUT et STDERR séparément
  • lire STDOUT et STDERR un nombre arbitraire d'octets à la fois alors que le processus est en cours d'exécution (par exemple, sans avoir à attendre la fin du processus)
  • détecter le moment où le processus est terminé
  • obtenir le code de sortie du processus

Merci d'avance pour vos réponses.

+0

Je sais que je peux faire plus de ce que je veux comme ceci: système ('commande 2> stderr.txt> stdout Ensuite, il suffit de lire les fichiers pendant que le processus est en cours d'exécution, mais je ne peux pas penser à un moyen facile de détecter quand le processus est terminé (qui n'implique pas l'analyse de sortie "ps ..." ou Quelque chose) ou obtenir son code de sortie – jnrbsn

Répondre

3

Vous pouvez rouler votre propre solution en utilisant l'interface d'appel système de Perl, mais il est plus facile d'utiliser le module intégré IPC :: Open3. Quant à votre liste:

Démarrer un processus externe:

use IPC::Open3; 
use IO::Handle; 
use strict; 

my $stdout = IO::Handle->new; 
my $stderr = IO::Handle->new; 
my $pid = open3(undef, $stdout, $stderr, 'my-command', 'arg1', 'arg2'); 

Lire STDOUT et STDERR séparément, un nombre arbitraire d'octets à la fois:

my $line = <$stdout>; 
# Or 
sysread $stderr, my $buffer, 1024; 

Detect lorsque le processus est terminé:

use POSIX qw(sys_wait_h); 

waitpid $pid, 0; # Waits for process to terminate 
waitpid $pid, WNOHANG; # Checks if the process has terminated 

Obtenir le code de sortie du processus:

my $status = $?; # After waitpid indicates the process has exited 

Assurez-vous de lire la documentation IPC :: Open3; Comme il le dit, il est facile de vous retrouver dans l'impasse quand vous avez des tuyaux stdout et stderr séparés, si vous ne faites pas attention. Si le processus enfant remplit l'un ou l'autre canal, il bloquera et si le processus parent lit le autre canal, le le bloquera.

2

Vous voulez ce module: IPC::Open3

+0

Merci pour la poussée dans la bonne direction (c'est tout ce dont j'avais vraiment besoin).Bien que, j'ai trouvé cet exemple plus utile (et plus pertinent à ma situation) que celui sur perldoc: http://docstore.mik.ua/orelly/perl/prog3/ch32_31.htm – jnrbsn

1

Vous voulez IPC :: Run, il capture l'IO et renvoie la valeur de sortie