IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Comment récupérer le code retour d'un batch windows en Perl ?


Sujet :

Langage Perl

  1. #1
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 887
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 887
    Par défaut Comment récupérer le code retour d'un batch windows en Perl ?
    Salut à tous.

    Je suis sous windows 10 Pro
    Je désire depuis un script Perl, lancer un batch windows et récupérer son code retour.

    Par exemple, ce batch windows :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    @echo off
     
    echo Le premier paramètre : %1
    echo Le second  paramètre : %2
     
    exit 5
    Et voici ce que j'ai fait en Perl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #!C:\perl64\bin\perl.exe -w
     
    use strict;
    use warnings;
    use diagnostics;
    use 5.24.1;
     
    # --------------------------------
    # Passage de paramètres à un Batch
    # --------------------------------
     
    my @cmd = ('batch.bat', 'hello', 'sir');
     
    open DATA, "@cmd|" or die "Ouverture impossible des données : $!" ;
     
    while (my $line = <DATA>)	{ $line =~ s/[\n\r]+//g; say ">>".$line."<<"; }
     
    close DATA;
    Et voici le résultat que j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>Le premier paramètre : hello<<
    >>Le second  paramètre : sir<<
    Avant de poster, j'ai cherché sur le net, sans succès.
    J'ai pensé que le code retour pouvait être récupéré par "$!" mais je n'obtiens rien à l'exécution.

    Je désire donc en Perl, récupérer la valeur 5.

    @+

  2. #2
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Pour récupérer le code retour d'un appel système, consulte la documentation de la fonction Perl system: https://perldoc.perl.org/functions/system.html

  3. #3
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 887
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 887
    Par défaut
    Salut Lolo78.

    Je dois aussi récupérer le résultat (stdout + stderr) de la commande.
    Du coup, je me retrouve à ne pas pouvoir utiliser la forme "open", celle que j'ai indiqué dans mon premier message, ni celle d'utiliser "system()".
    Il me reste alors que la solution consistant à utiliser les backticks, que voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #!C:\perl64\bin\perl.exe -w
     
    use strict;
    use warnings;
    use diagnostics;
    use 5.24.1;
     
    # --------------------------------
    # Passage de paramètres à un Batch
    # --------------------------------
     
    my @cmd = ('Batch.bat', 'hello', 'sir', '2>&1');
     
    my $res    = `@cmd`;
    my $codret = $? >> 8;
     
    foreach (split /\n/, $res) { say ">>>".$_."<<<"; }
     
    say ">>> code retour = ".$codret;
    Dans le lien que vous m'avez communiqué, il faut appliquer ceci "$? >> 8" pour récupérer le code retour du batch. Quel est la différence avec "$!" ?

    Existe-t-il d'autres approches pour gérer des appels systèmes ?

    @+

  4. #4
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    attention, les backticks capturent le résultat stdout de la commande, mais à ma connaissance pas stderr. A moins de rediriger stderr vers stdout, c'est apparemment ce que tu fais dans ta commande shell/batch.

    $? renvoie le statut de la dernière commande système (system, backticks ou autre), alors que $! renvoie le libellé (ou le numéro en contexte numérique) de la dernière erreur. Donc, $! n'est pas alimenté s'il n'y a pas d'erreur. Je ne suis pas entièrement sûr de comment cette différence se traduit exactement sous Windows (et je ne suis pas sûr que le décalage de 8 soit adapté à Windows).

    Il existe des modules CPAN permettant de gérer ces différents éléments de façon plus simple. Voir par exemple IPC::System::Simple (http://search.cpan.org/~pjf/IPC-Syst...stem/Simple.pm).

    Voir aussi le module System::Command (http://search.cpan.org/~book/System-...tem/Command.pm). Il y en a certainement d'autres, à toi de choisir selon tes besoins.

  5. #5
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 887
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 887
    Par défaut
    Salut lolo78.

    Citation Envoyé par Lolo78
    attention, les backticks capturent le résultat stdout de la commande, mais à ma connaissance pas stderr.
    Oui, en effet, vous avez raison.

    Citation Envoyé par Lolo78
    A moins de rediriger stderr vers stdout, c'est apparemment ce que tu fais dans ta commande shell/batch.
    C'est bien la solution que j'ai adopté afin de récupérer aussi les erreurs.

    Citation Envoyé par Lolo78
    $? renvoie le statut de la dernière commande système (system, backticks ou autre)
    D'après ce que j'ai compris, c'est le statut (ou code retour) de la dernière commande pipeline.
    Et toujours d'après ce que j'ai compris, il n'y a pas d'autres cas que "system()" et les backticks.

    Citation Envoyé par Lolo78
    alors que $! renvoie le libellé (ou le numéro en contexte numérique) de la dernière erreur.
    Je pense que cela concerne l'erreur système et non l'erreur logique qu'un Batch Windows peut retourner.

    Citation Envoyé par Lolo78
    Donc, $! n'est pas alimenté s'il n'y a pas d'erreur.
    Même pas un zéro pour dire que tout c'est bien passé ?

    Citation Envoyé par Lolo78
    Je ne suis pas entièrement sûr de comment cette différence se traduit exactement sous Windows
    Il faut faire la distinction entre le lancement de la commande et son résultat.
    Pour une raison que j'ignore, la commande peut ne pas s'exécuter. Je pense que c'est le rôle de "$!" de nous renseigner sur cette erreur.
    Mais quand la commande s'exécute, elle peut aussi nous retourner une erreur de fonctionnement. Et c'est le rôle de "$?".

    Citation Envoyé par Lolo78
    et je ne suis pas sûr que le décalage de 8 soit adapté à Windows.
    Il est obligatoire, sinon je ne peux pas récupérer le code retour !

    Citation Envoyé par Lolo78
    Il existe des modules CPAN permettant de gérer ces différents éléments de façon plus simple.
    Pour l'instant, je préfère utiliser ce que propose d'une manière native (ou standard) le Perl ( Version 5.24.1).

    Citation Envoyé par Lolo78
    Voir par exemple IPC::System::Simple (http://search.cpan.org/~pjf/IPC-Syst...stem/Simple.pm).
    IPC = interprocess communication. Je n'ai aucun usage de la communication inter processus.

    Citation Envoyé par Lolo78
    Voir aussi le module System::Command (http://search.cpan.org/~book/System-...tem/Command.pm).
    Je n'en aurai pas trop l'usage non plus.

    Citation Envoyé par Lolo78
    Il y en a certainement d'autres, à toi de choisir selon tes besoins.
    Je désire faire de l'habillage de programmes afin de faire un minimum de manipulation.
    Et vu que la plupart du temps, ce sont les mêmes erreurs à gérer, je pense pouvoir automatiser ces problèmes.

    Le pire est que chaque traitement gère ses anomalies comme bon lui semble.
    Parfois, c'est un code retour, et parfois dans le flux des messages reçus, il y a un message d'anomalie à traiter.
    C'est pourquoi, j'étais parti sur une gestion de flux comme si j'avais un fichier.

    @+

  6. #6
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Artemus24 Voir le message
    Salut lolo78.

    D'après ce que j'ai compris, c'est le statut (ou code retour) de la dernière commande pipeline.
    Et toujours d'après ce que j'ai compris, il n'y a pas d'autres cas que "system()" et les backticks.
    Il y a également close sur un pipe, wait ou waitpid.

    Citation Envoyé par Artemus24 Voir le message
    Je pense que cela concerne l'erreur système et non l'erreur logique qu'un Batch Windows peut retourner.
    Exact. Une erreur logique retournée dans un batch, c'est dans le statut ou code retour.

    Si en revanche le batch plante par exemple parce qu'il ne trouve pas un fichier à ouvrir ou à copier, ce sera en principe une erreur système dans $!.

    Citation Envoyé par Artemus24 Voir le message
    Même pas un zéro pour dire que tout c'est bien passé ?
    Non, à ma connaissance la variable est soit undef soit une chaîne vide. Mais une valeur undef et la chaîne vide sont toutes deux évaluées à faux (comme zéro) dans un contexte booléen.

    Citation Envoyé par Artemus24 Voir le message
    Pour l'instant, je préfère utiliser ce que propose d'une manière native (ou standard) le Perl ( Version 5.24.1).
    Comme tu veux... Cela marche tant que ça reste simple et c'est aussi ce que je préfère faire dans la mesure du possible.

    Citation Envoyé par Artemus24 Voir le message
    IPC = interprocess communication. Je n'ai aucun usage de la communication inter processus.
    Quand tu lances une commande système, tu lances en fait un autre processus et ce module permet de bien communiquer avec le processus fils que tu as lancé. Consulte la doc, il est précisément destiné au genre de choses que tu cherches à faire. (Et l'autre module aussi). Pour des cas un peu compliqué, ce module te donne beaucoup plus de finesse de gestion des situations.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment récupérer un code retour SFTP ?
    Par hervé94 dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 28/08/2007, 20h45
  2. [C#]Comment récupérer le code d'une Exception ?
    Par joujoukinder dans le forum C#
    Réponses: 18
    Dernier message: 30/07/2007, 01h47
  3. Récupérer le code retour d'un batch
    Par mick84m dans le forum Linux
    Réponses: 4
    Dernier message: 11/05/2005, 17h09
  4. Réponses: 5
    Dernier message: 21/12/2004, 18h12
  5. [commande DOS] Récupérer le code retour d'un programme
    Par bobunny dans le forum Scripts/Batch
    Réponses: 8
    Dernier message: 04/06/2004, 15h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo