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 :

résultat d'une fonction dans un tableau


Sujet :

Langage Perl

  1. #1
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut résultat d'une fonction dans un tableau
    Bonjour
    J'ai une fonction dont le résultat est dans la variable $File::Find::name et je désire l'insérer dans une tableau. Pour cela j'ai utilisé la fonction push() mais malheureusement le premier élément du tableau est null.
    Dois-je utiliser autre chose que la fonction push ou y-a-t il une meilleures solutions?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    [...]
    sub want {
      (int(-C _) < 1) &&
      (int(-M _) < 1) &&
      ( /^.*\.log\z/s || /^.*\.*gz\z/s || /^.*\.tmp\z/s) &&
      push (@array, "$File::Find::name");
      return @array;
    }
    nymus

  2. #2
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Passe plutôt une référence vers ton tableau. (En fait tu peux retourner une liste, voir jouer sur le retour scalaire ou liste, mais je pense que ce que tu veux là c'est une référence sur un tableau).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $result = [];
    push @$result, $name;
    return $result;
    Ensuite bien sûr tu déréférences lors de l'accès aux éléments : $array->[0] etc.

  3. #3
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Au fait, tu es sûr que find a trouvé quelque chose ?

    (J'avais pas vu tes quotes et donc tu pousses vraisemblablement bien une chaîne vide)

  4. #4
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut
    Oui, je reçois bien quelque choses...
    En fait, pour bien préciser les choses; La création(remplissage) de mon tableau s'effectue au niveau du push. C'est-à-dire qu'auparavant mon tableau est vide (il y a juste une déclaration : my @array;!
    Mon idée est d'obtenir un tableau avec les fichiers que "find" à trouver ensuite mon script appellera une autre fonction qui détruira ces fichiers spécifiques... c'est peut-être un peu lourd, mais je pensait bien structuré mon programme avec une fonction de recherche et une de destruction. Dans l'idées de pouvoir par la suite de les utilisées séparément pour d'autres applications...

    Qu'en penses-tu?

  5. #5
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Je comprends, maintenant.

    Premier problème. La valeur de retour de want() – la fonction que tu passes en call-back à File::Find – n'a aucune importance : elle est ignorée par File::Find.

    Autre problème : tu utilises _ sans avoir appelé lstat d'abord (_ cache le résultat du dernier lstat, ce qui évite de l'appeler à plusieurs reprises dans le test).

    Sinon, tu peux bien sûr appeler une fonction de traitement du fichier trouver dans ton call-back (en lui passant $File::Find::name) si tu ne veux pas faire le traitement lui-même dans le call-back.

    Montre ton code, comme ça on verra mieux ce que tu veux exactement faire.

  6. #6
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut
    Merci pour toutes ces explications...
    Voici mon code:
    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
    42
    43
    44
     
    #!/usr/bin/perl -w
     
    use strict;
    use Time::localtime;
    use File::stat;
    use Switch;
    use File::Find;
     
    my @array= "";
     
    # ctime + mtime : -1
    # files: *.log + *.gz + *.tmp
    sub want {
      (int(-C _) < 1) &&
      (int(-M _) < 1) &&
      ( /^.*\.log\z/s || /^.*\.*gz\z/s || /^.*\.tmp\z/s) &&
      push (@array, $File::Find::name);
      return @array;
    }
     
    sub listdir{
       my $dirname = $_[0];
       foreach($dirname){
         logfile("call func. listdir for $dirname");
         opendir ( DIR, $dirname ) || die logfile ("Error in opening dir $dirname\n");
         find(\&want, $dirname);
       }
       closedir DIR;
    }
    #
    # Begin program
    #--------------
    my @list = ('/usr/local/sbin','/var/log','/opt/nagios_plugins');
    my $path;
     
    foreach $path (@list){
      print ("PATH : $path\n");
      listdir($path);
    }
    foreach(@array){
      print ("file: $_\n");
    }
    printf ("total files : $#array\n");

  7. #7
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Ok. Il y a plein de (petites) choses qui ne vont pas.

    Si tu veux un tableau avec les noms de fichiers, cela (simplifié) donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my @dirs = qw{/usr/local/sbin /var/log};
    my @paths; # ou = (); mais pas = '';
    find( sub { /^.*\.tmp\z/s && push @paths, $File::Find:name } , @dirs);
    Comme tu vois, tu passes une fonction de call-back et une liste de répertoires.

    Bon, ça c'est dans le cas où tu veux construire une liste. Mais tu n'en as pas vraiment besoin.

    Ce qui ne vas toujours pas non plus, c'est ton usage de _ sans appel à stat.

    Voilà un exemple (pas testé, juste pour l'idée):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    find( \&want , qw{/usr/local/sbin /var/log}); 
     
    sub want {
        /^.*\.tmp\z/s &&
            my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime) = stat($_)) &&
            $mtime < 1 && 
            treat($File::Find::name) ;
    }
     
    sub treat {
        my $filename = shift;
        # ...
        return 1;
    }

  8. #8
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut
    Pour quelle raison préconises-tu le qw{}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @dirs = qw{/usr/local/sbin /var/log};
    plutôt que ma déclaration???
    Ensuite ne pourrait on pas utiliser directement la commande plutôt que toute la liste?
    Ce soir, je n'ai plus le temps mais je testerai cela demain et te tiendrai informé

    Dans tous les cas, ca simplifie vraiment le code... et un grand merci!

    Bonne soirée

  9. #9
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut
    Je reviens à la charge avec mes questions!
    Pour bien trouver mon erreur, j'ai retapé un petit script de test, 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
    20
    21
     
    #!/usr/bin/perl -w
    use strict;
    use Time::localtime;
    use File::stat;
    use Switch;
    use File::Find;
     
    sub want {
      my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks);
    (($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($_));
      print ("mtime : $mtime\n");
      treat($File::Find::name);
    }
    sub treat {
      my $filename = shift;
      print ("filename : $filename\n");
      return 1;
    }
    my @dirs = qw{/usr/local/sbin/Tests};
    find ( \&want, @dirs);
    Tout con! mais perl ne trouve pas la valeur du $mtime!!!
    Use of uninitialized value $mtime in concatenation (.) or string at ./find_file_test.pl line 11
    Quelqu'un aurait-il une idée??????

    Cordialement
    nm

  10. #10
    Mr6
    Mr6 est déconnecté
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Septembre 2004
    Messages
    607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2004
    Messages : 607
    Points : 794
    Points
    794
    Par défaut
    Salut !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sub want {
    print "ma variable courante contient ? $_\n";
    ......
    Qu'est ce que ca renvoie ?

    @+
    Mr6

  11. #11
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut
    Salut Mr6

    J'ai rajouté ton bout de code dans mon script et voici le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [...]
    filename : /usr/local/sbin/Tests/check_sdh.sh
    ma variable courante contient ? delete_oldfiles.pl
    filename : /usr/local/sbin/Tests/delete_oldfiles.pl
    ma variable courante contient ? array_test.pl
    filename : /usr/local/sbin/Tests/array_test.pl
    ma variable courante contient ? test_mount.pl
    filename : /usr/local/sbin/Tests/test_mount.pl
    ma variable courante contient ? prog.stderr
    [...]
    Il renvois le nom du fichier...
    A+

  12. #12
    Mr6
    Mr6 est déconnecté
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Septembre 2004
    Messages
    607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2004
    Messages : 607
    Points : 794
    Points
    794
    Par défaut
    Visiblement stat() renvoie un arrayref, donc un print $dev devrait te renvoyer File::stat=ARRAY(0x....).
    Donc si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my $stats = stat($_);
    print "mtime : $stats->[9]\n";
    Tu devrais avoir un meilleur résultat.

    Du coup je viens de relire tes précédents messages, et en fait tu peux effectivement écrire directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    treat($File::Find::name) if stat($_)->mtime < 1;
    @+
    Mr6

  13. #13
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut
    Merci beaucoup...
    Le résultat est meilleurs mais quelque chose me rend perplexe....
    Maintenant j'obtiens bien le -mtime, qui est défini par perldoc :
    http://perldoc.perl.org/functions/stat.html
    9 mtime last modify time in seconds since the epoch
    Donc, la valeur est d'environ : 1259836490.
    Si je reviens un peu plus haut dans mes discussions, le script fournit par find2perl me donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    (($dev,$ino,$mode,$nlink,$uid,$gid) = stat($_)) &&
        (int(-C _) < 1) && [...]
    la valeur de int(-C _) me fournit le nombre de jour depuis la création du fichier, genre : 1,2,etc... et non le nombre de seconde depuis epoch!
    Définition de perldoc :
    http://perldoc.perl.org/functions/-X.html
    -C Same for inode change time (Unix, may differ for other platforms)
    Mes interrogations :
    -Ces deux définitions parlent de -mtime mais les valeurs que j'obtiens sont différentes???
    -la fonction find à une option de -mtime qui correspondrait au deuxième cas, exsite-il plusieurs sortes de mtime???
    -(int(-C _) prends l'info en provenance de find ou est fournit pas stat($_)???

    Désolé de poser toutes ces questions, mais je butte depuis un moment sur ces différences...

    nymus

  14. #14
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Ces deux définitions parlent de -mtime mais les valeurs que j'obtiens sont différentes???
    Non la 2eme définition parle de ctime qui concerne la modification de l'inode, autrement appelé le statut du fichier, par exemple suite à changement du nom, du propriétaire, des droits d'accès... Dans la structure stat, il y a ctime, atime et mtime, atime étant la date du dernier accès en lecture.

  15. #15
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut
    Oui, tu as raison et merci pour les explications...
    Ce que je ne comprends pas pourquoi j'obtiens deux résultats différents de A) par rapport au B).
    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
    CODE A)
    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($_);
    my $mtime = (-M _);
    [...]
    mtime : 13.1867361111111
    mtime : 12.0462731481481
    mtime : 12.0462731481481
    mtime : 12.1386342592593
    [...]
    CODE B)
    my $stats = stat ($_);
    print "ma variable courante contient ? $_\n";
    print "mtime : $stats->[9]\n";
    print "ctime : $stats->[10]\n";
    [...]
    mtime : 1259836490
    ctime : 1259836490
    mtime : 1259836490
    ctime : 1259836490
    mtime : 1259836490
    ctime : 1259836490
    [...]
    CODE A) en jour et CODE B) ????

  16. #16
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    La doc (perldoc "-f") dit:
    -M Script start time minus file modification time, in days.
    =Date de début du script moins date de dernière modification du fichier, en jours.
    alors que le champ mtime est un nombre de secondes écoulées depuis le 1er janvier 1970 (="seconds since the epoch")

  17. #17
    Membre régulier
    Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2007
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Août 2007
    Messages : 147
    Points : 77
    Points
    77
    Par défaut
    Ouahhh... j'ai enfin trouvé une réponse à ma question!
    Merci mille fois

Discussions similaires

  1. Afficher le résultat d'une fonction dans un tableau
    Par aminaloli dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 27/08/2012, 10h21
  2. Réponses: 12
    Dernier message: 09/01/2007, 19h04
  3. Réponses: 3
    Dernier message: 30/11/2006, 06h25
  4. Récupérer le résultat d'une fonction dans une balise html
    Par Hayato dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 19/06/2006, 17h04
  5. Réponses: 6
    Dernier message: 08/06/2006, 10h07

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