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 :

Erreur: bad file descriptor


Sujet :

Langage Perl

  1. #1
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 49
    Points : 26
    Points
    26
    Par défaut Erreur: bad file descriptor
    Bonjour

    j'ai écrit un script (avec votre aide ) et quand je l'exécute, j'ai un message d'erreur que je n'arrive pas à corriger. Voici le script:
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #!C:/perl/bin/perl -w
     
    use strict;
    use List::Util qw(min);
     
    my $date=localtime;
     
    open ( STDOUT, ">delete_logsdb2_pl.log" ) or die "Impossible d'ouvrir delete_logsdb2_pl.log : $!\n";
     
    print "\n************ $date: DEBUT DU SCRIPT $0  ************\n\n";
     
    my $query_full = "D:/sqllib/bin/db2adutl query full db $ARGV[0]";
     
    print "$query_full\n";
     
    system ("$query_full") or die "\n************ $date: FIN ANORMALE DE LA COMMANDE $query_full : $!\n\n";
     
    open ( OUT, "<delete_logsdb2_pl.log" ) or die "\n************ $date: FIN ANORMALE DU SCRIPT $0: $!\n\n";
     
    my $contenu = do {local $/; <OUT> };
     
    close ( OUT );
     
    my @matches = $contenu =~ m/S(\d{7})\.LOG/g;
     
    my $log_util = min (@matches) - 1;
     
    my $result = sprintf "S%07i.LOG\n", $log_util;
     
    my $delete_logs = "D:/sqllib/bin/db2adutl delete logs db $ARGV[0] between S0000000.LOG and ".$result." without prompting";
     
    print "$delete_logs\n";
     
    system ("$delete_logs") or die "\n************ $date: FIN ANORMALE DE LA COMMANDE $delete_logs : $!\n\n";
     
    print "\n************ $date: FIN NORMALE DU SCRIPT $0  ************\n\n";
    Lors de l'exécution, le message est le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    C:\bat>delete_logsdb2.pl DBRD5PMD
     
    ************ Thu Sep  6 09:34:59 2007: FIN ANORMALE DE LA COMMANDE D:/sqllib/bin/db2adutl query full db DBRD5PMD : Bad file descriptor
    Voyez-vous une explication à ce problème ?

    Merci d'avance.
    Cordialement,
    Bruno

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    A priori c'est la commande elle même qui échoue, que se passe-t-il si tu la tapes en ligne de commande ?

    --
    Jedaï

  3. #3
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 49
    Points : 26
    Points
    26
    Par défaut
    La commande me génère une log de ce type:
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    ************ Thu Sep  6 11:27:17 2007: DEBUT DU SCRIPT C:\bat\delete_logsdb2.pl  ************
     
    D:/sqllib/bin/db2adutl query full db DBRD5PMD
     
    Query for database DBRD5PMD
     
     
    Retrieving FULL DATABASE BACKUP information.
        1 Time: 20070906023015  Oldest log: S0016669.LOG  Node: 0    Sessions: 1  
        2 Time: 20070905023034  Oldest log: S0016661.LOG  Node: 0    Sessions: 1  
        3 Time: 20070904023019  Oldest log: S0016653.LOG  Node: 0    Sessions: 1  
        4 Time: 20070903023022  Oldest log: S0016644.LOG  Node: 0    Sessions: 1  
        5 Time: 20070902023019  Oldest log: S0016634.LOG  Node: 0    Sessions: 1  
        6 Time: 20070901023018  Oldest log: S0016625.LOG  Node: 0    Sessions: 1  
        7 Time: 20070831023018  Oldest log: S0016615.LOG  Node: 0    Sessions: 1  
        8 Time: 20070830023021  Oldest log: S0016606.LOG  Node: 0    Sessions: 1  
        9 Time: 20070829023015  Oldest log: S0016597.LOG  Node: 0    Sessions: 1  
       10 Time: 20070828023018  Oldest log: S0016222.LOG  Node: 0    Sessions: 1  
       11 Time: 20070827023025  Oldest log: S0016213.LOG  Node: 0    Sessions: 1  
       12 Time: 20070826023024  Oldest log: S0016203.LOG  Node: 0    Sessions: 1  
       13 Time: 20070825023024  Oldest log: S0016194.LOG  Node: 0    Sessions: 1  
       14 Time: 20070824023017  Oldest log: S0016184.LOG  Node: 0    Sessions: 1  
       15 Time: 20070823023017  Oldest log: S0016174.LOG  Node: 0    Sessions: 1  
       16 Time: 20070822023017  Oldest log: S0016163.LOG  Node: 0    Sessions: 1  
       17 Time: 20070821023019  Oldest log: S0015988.LOG  Node: 0    Sessions: 1  
       18 Time: 20070820023015  Oldest log: S0015979.LOG  Node: 0    Sessions: 1  
       19 Time: 20070819023012  Oldest log: S0015971.LOG  Node: 0    Sessions: 1  
       20 Time: 20070818023013  Oldest log: S0015963.LOG  Node: 0    Sessions: 1  
       21 Time: 20070817023012  Oldest log: S0015955.LOG  Node: 0    Sessions: 1  
     
    D:/sqllib/bin/db2adutl delete logs db DBRD5PMD between S0000000.LOG and S0015954.LOG
     without prompting
     
    Query for database DBRD5PMD
     
     
    Retrieving LOG ARCHIVE information.
      No LOG ARCHIVE images found for DBRD5PMD
     
     
    ************ Thu Sep  6 11:27:17 2007: FIN NORMALE DU SCRIPT C:\bat\delete_logsdb2.pl  ************
    Manuellement, la commande fonctionne bien, elle me donne la liste des fichiers Sxxxxxxx.LOG.

    Maintenant, le script fonctionne correctement.
    J'ai simplement enlevé les "or die" qui suivaient les commandes "system ()" et je n'ai plus de plantage.

    Je ne sais pas donner l'explication de ce phénomène ...

    Question subsidiaire: Au début du script, je redirige la STDOUT dans un fichier, mais je souhaiterais avoir aussi les messages à l'écran. Comment faire pour écrire sur plusieurs sorties simultanémént ?

    Merci d'avance pour votre aide.
    Cordialement,
    Bruno

  4. #4
    Membre éprouvé Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Points : 1 118
    Points
    1 118
    Par défaut
    tu peux afficher le contenu de ton fichier avec un tail -f sur le fichier de log...

    ou alors te servir de STDOUT pour le fichier et de STDERR pour la sortie dans la console (ou inversement)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    print STDOUT "sortie standard\n";
    print STDERR "sortie d'erreur\n";
    Si tu n'as redirigé que la sortie standard dans un fichier, la sortie d'erreur elle continue d'être redirigée vers l'écran

    Je ne répond à aucune question technique par MP.

    Si votre problème est réglé, n'oubliez pas Dans tous les cas

  5. #5
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 49
    Points : 26
    Points
    26
    Par défaut
    ok, ça n'a pas l'ai si simple que çà !!

    En fait, n'existe t-il pas en perl un equivalent de la commande ksh: " | tee -a /tmp/fichier.log" ?

  6. #6
    Membre éprouvé Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Points : 1 118
    Points
    1 118
    Par défaut
    ben si, c'est aussi simple... sinon, 3° solution, au lieu de rediriger STDOUT dans un fichier de log à la création du script, te faire ton propre print personnalisé qui effectue la sortie dans un fichier de log ET à l'écran.

    En gros, au lieu de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    open ( STDOUT, ">delete_logsdb2_pl.log" ) or die "Impossible d'ouvrir delete_logsdb2_pl.log : $!\n";
    print("toto\n");
    tu vas faire:

    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
     
    # au début, on ouvre le log de la même manière, mais dans un une variable $log plutot que rediriger stdout dedans
    open (my $log, '>', 'delete_logsdb2_pl.log') or die "Impossible d'ouvrir delete_logsdb2_pl.log : $!\n";
     
    # une petite méthode qui effectue la sortie standard
    sub myprint {
        my ($message) = @_;
        print $log $message; # on écrit dans le log
        print STDOUT $message; # on écrit dans la console
    }
     
    # au lieu de faire print(), tu fais myprint(), et ca affiche à la fois dans le log et dans la console
    myprint("toto\n");
     
    # à la fin, on ferme le log
    close($log);

    Je ne répond à aucune question technique par MP.

    Si votre problème est réglé, n'oubliez pas Dans tous les cas

  7. #7
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Et si tu veux une solution générale, tu peux aussi utiliser IO::Tee.

    --
    Jedaï

  8. #8
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 49
    Points : 26
    Points
    26
    Par défaut
    Merci beaucoup pour cette 3eme solution mais en l'occurrence elle ne peut pas convenir dans mon cas car les messages que je veux recupérer à la fois dans mon log et à l'écran ne sont pas générés que par des print mais par des programmes appelés avec "system()".

    Pourquoi est-ce que je veux avoir les deux sorties ? Car ce scripts est ordonnacé par un automate qui, lui, capte les messages sur la sortie standard. Par contre, pour les besoins du job, j'ai besoin d'avoir accès à ce qui est généré par les commandes sql à postériori. Donc la sortie standard doit être dupliquée (console + log). C'est pour cela que je cherche à simuler la commande shell "tee -a".
    Et je ne peux même pas l'appeler à travers une commande system car je travaille sur windows ....
    Enfin voilà, je reste à l'écoute si toutefois kkun a une idée ...

    Merci d'avance
    Cordialement,
    Bruno

    EDIT: Oups ... je n'avais pas vu la réponse de Jedai !! Désolé ! Je vais de suite voir Io::Tee.
    Merci encore !

  9. #9
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 49
    Points : 26
    Points
    26
    Par défaut
    Une solution qui m'irait bien c'est de pouvoir rediriger STDOUT à sa valeur d'origine après avoir récupéré ce que je veux dans la log.

    Donc la question est:

    A l'origine, STDOUT écrit sur la console.
    Je la redirige dans un fichier avec le open (STDOUT ....
    Comment la rediriger de nouveau vers la console ? (si je fait close (STDOUT), ça n'écrit plus nulle part !)

  10. #10
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    La page de doc de open() a un exemple pour ça (redirection de STDOUT et STDERR puis retour aux anciennes sorties) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/perl
    open my $oldout, '>&', \*STDOUT
      or die "Can't dup STDOUT: $!";
     
    open STDOUT, '>', "foo.out" or die "Can't redirect STDOUT: $!";
     
    # this works for subprocesses too
    print STDOUT "stdout 1\n";	
     
    open STDOUT, '>&', $oldout 
      or die "Can't dup \$oldout: $!";
     
    print STDOUT "stdout 2\n";
    --
    Jedaï

  11. #11
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 49
    Points : 26
    Points
    26
    Par défaut
    Ok merci bcp ! J'ai mis perldoc.perl.org dans mes favoris pour consultation en premier lieu la prochaine fois !
    Bonne continuation.
    Bruno

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

Discussions similaires

  1. Erreur : Bad file descriptor sur socket
    Par TariC dans le forum Réseau
    Réponses: 2
    Dernier message: 22/11/2010, 20h31
  2. Bad File descriptor avec fcntl
    Par guigui31 dans le forum Débuter
    Réponses: 2
    Dernier message: 21/04/2008, 20h11
  3. Réponses: 0
    Dernier message: 18/11/2007, 20h53
  4. Bad file descriptor avec un read()
    Par je®ome dans le forum C
    Réponses: 2
    Dernier message: 04/04/2006, 19h30
  5. Etrange "Bad file descriptor"
    Par amauryxiv dans le forum Langage
    Réponses: 23
    Dernier message: 01/02/2006, 03h20

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