Comment capturer les commandes stdin et stdout de la commande système à partir d'un script Perl?

StackOverflow https://stackoverflow.com/questions/78091

  •  09-06-2019
  •  | 
  •  

Question

Au milieu d'un script Perl, il y a une commande système que je veux exécuter. J'ai une chaîne qui contient les données qui doivent être introduites dans stdin (la commande n'accepte que les entrées de stdin), et j'ai besoin de capturer la sortie écrite dans stdout. J'ai examiné différentes méthodes d'exécution de commandes système en Perl, et la fonction open semble être ce dont j'ai besoin, à ceci près qu'il semble que je ne peux capturer que stdin ou stdout, pas les deux.

Pour le moment, il semble que ma meilleure solution consiste à utiliser open , à rediriger stdout dans un fichier temporaire et à le lire à la fin de la commande. Y a-t-il une meilleure solution?

Était-ce utile?

La solution

Je pense que vous souhaitez jeter un oeil à IPC :: Open2

Autres conseils

IPC :: Open2 / 3, ça va, mais j’ai découvert que tout ce dont j’ai besoin est en général IPC :: Run3 , qui gère très bien les cas simples avec une complexité minimale:

use IPC::Run3;    # Exports run3() by default

run3( \@cmd, \$in, \$out, \$err );

La documentation compare IPC :: Run3 à d'autres alternatives. Cela vaut la peine d'être lu même si vous ne décidez pas de l'utiliser.

La la documentation perlipc couvre de nombreuses manières de le faire, y compris IPC :: Open2 et IPC :: Open3.

Quelque part en haut de votre script, insérez la ligne

use IPC::Open2;

Cela inclura le module nécessaire, généralement installé avec la plupart des distributions Perl par défaut. (Si vous ne l'avez pas, vous pouvez l'installer à l'aide de CPAN.) Ensuite, au lieu d'ouvrir, appelez:

$pid = open2($cmd_out, $cmd_in, 'some cmd and args');

Vous pouvez envoyer des données à votre commande en l'envoyant à $ cmd_in, puis lire le résultat de votre commande en lisant à partir de $ cmd_out.

Si vous souhaitez également pouvoir lire le flux stderr de la commande, vous pouvez utiliser le module IPC :: Open3 à la place.

IPC :: Open3 ferait probablement ce que vous voulez. Il peut capturer STDERR et STDOUT.

http://metacpan.org/pod/IPC::Open3

Si vous ne souhaitez pas inclure de packages supplémentaires, vous pouvez simplement faire

open(TMP,">tmpfile");
print TMP  $tmpdata ;
open(RES,"$yourcommand|");
$res = "" ;
while(<RES>){
$res .= 

Si vous ne souhaitez pas inclure de packages supplémentaires, vous pouvez simplement faire

<*>

ce qui est le contraire de ce que vous avez suggéré, mais devrait également fonctionner.

; }

ce qui est le contraire de ce que vous avez suggéré, mais devrait également fonctionner.

Je le fais toujours de cette façon si je n'attends qu'une seule ligne de sortie ou si je souhaite fractionner le résultat sur autre chose qu'une nouvelle ligne:

my $result = qx( command args 2>&1 );  
my $rc=$?;  
# $rc >> 8 is the exit code of the called program.

if ($rc != 0 ) {  
    error();  
}  

Si vous souhaitez gérer une réponse sur plusieurs lignes, obtenez le résultat sous forme de tableau:

my @lines = qx( command args 2>&1 );  

foreach ( my $line ) (@lines) {  
    if ( $line =~ /some pattern/ ) {  
        do_something();  
    }  
}  
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top