Comment capter stderr, stdout, et le code de sortie à la fois, en Perl?
Est-il possible de lancer un processus externe de Perl, la capture de son stderr, stdout ET le code de sortie du processus?
Je semble être en mesure de faire des combinaisons de ceux-ci, par exemple l'utilisation des backticks pour obtenir stdout, IPC::Open3 pour capturer des sorties, et system() pour obtenir les codes de sortie.
Comment capter stderr, stdout, et le code de sortie tout à la fois?
Vous devez vous connecter pour publier un commentaire.
Si vous relisez la documentation de IPC::Open3, vous verrez une note que vous devez appeler waitpid de récolter le processus de l'enfant. Une fois que vous faites cela, l'état doit être disponible dans
$?
. La valeur de sortie est$? >> 8
. Voir$?
dans perldoc perlvar.(Mise à jour: j'ai mis à jour l'API pour les IO::CaptureOutput pour rendre le tout encore plus facile.)
Il y a plusieurs façons de le faire. Voici une option, à l'aide de la IO::CaptureOutput module:
C'est le capture_exec() de la fonction, mais IO::CaptureOutput dispose également d'une manière plus générale à la capture() fonction qui peut être utilisée pour capturer soit Perl de sortie ou de sortie à partir d'applications externes. Donc si l'un module Perl qui se passe à l'utilisation de certains programme externe, vous obtenez toujours la sortie.
Elle aussi signifie que vous ne devez pas perdre de vue une approche unique pour la capture de STDOUT et STDERR (ou la fusion) au lieu de l'aide de l'IPC::Open3 pour les programmes externes et d'autres modules pour la capture de Perl sortie.
Si vous ne voulez pas le contenu de STDERR, la capture() la commande de IPC::System::Simple module est presque exactement ce que vous recherchez:
Vous pouvez utiliser la capture() avec un seul argument à invoquer le shell, ou plusieurs arguments fiable pour éviter que le shell. Il y a aussi capturex() qui n'appelle jamais la coquille, même avec un seul argument.
Contrairement au Perl intégré dans le système et backticks des commandes, de l'IPC::System::Simple renvoie la 32 bits de sortie de la valeur sous Windows. Il jette également un détaillé exception si la commande ne peut pas être démarré, meurt à un signal, ou est de retour inattendu de la valeur de sortie. Cela signifie pour de nombreux programmes, plutôt que de vérifier les valeurs de retour de vous-même, vous pouvez compter sur
IPC::System::Simple pour faire le travail dur pour vous:
IPC::System::Simple est de la pure Perl, n'a pas de dépendances, et fonctionne sur Unix et les systèmes Windows. Malheureusement, il ne fournit pas un moyen de capturer la sortie STDERR, de sorte qu'il peut ne pas être adapté à tous vos besoins.
IPC::Run3 fournit un environnement propre et facile de l'interface en re-plomberie tous les trois descripteurs, mais malheureusement, il ne vérifie pas si la commande a été couronnée de succès, de sorte que vous aurez besoin d'inspecter $? manuellement, ce qui n'est pas du tout amusant. En fournissant une interface publique pour l'inspection de $? c'est quelque chose qui est sur mon liste de choses à faire de l'IPC::System::Simple, depuis l'inspection de $? dans une croix-plate-forme de la mode n'est pas une tâche que j'avais souhaitez sur n'importe qui.
Il y a d'autres modules dans le IPC:: espace de noms peut également vous fournir de l'aide. YMMV.
Tout le meilleur,
Paul
Il existe trois méthodes de base de l'exécution de commandes externes:
Avec
system()
, à la foisSTDOUT
et STDERR vont au même endroit que le script estSTDOUT
etSTDERR,
à moins que lesystem()
commande redirige. Backticks etopen()
à lire que lesSTDOUT
de votre commande.Vous pouvez aussi appeler quelque chose comme ce qui suit avec ouverte pour rediriger les deux
STDOUT
etSTDERR
.Le code de retour est toujours stocké dans
$?
comme l'a noté @Michael Carman.qx//
Si vous vous sentez vraiment compliqué, vous pourriez vouloir essayer de s'Attendre.pm. Mais c'est sans doute exagéré si vous n'avez pas besoin de gérer l'envoi d'entrée pour le processus.
J'ai trouvé IPC:run3 pour être très utile. Vous pouvez transférer tous les enfants des tuyaux à une boule ou une variable, très facilement! Et code de sortie sera stocké dans $?.
Ci-dessous comment j'ai attrapé stderr dont je savais qu'il serait un certain nombre. Le cmd de sortie informatic transformations vers stdout (que j'ai joué à un fichier dans le args à l'aide de >) et a rapporté comment de nombreuses transformations vers STDERR.