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 :

Perl et commande shell


Sujet :

Langage Perl

  1. #1
    Membre régulier

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 90
    Points : 119
    Points
    119
    Par défaut Perl et commande shell
    Bonjour,

    J'aimerai supprimer récursivement les fichiers contenu dans Proj/ :
    En shell,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find /home/user/Proj/ -name "*.*" -exec rm -rf "{}" \;
    fonctionne très bien.

    J'aimerai maintenant l'insérer dans mon code perl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my $com = `find /home/user/Proj/ -name "*.*" -exec rm -rf "{}" \;`;
    my $res = system($com);
    Mais cela ne marche pas, mais affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find: Paramètre manquant pour « -exec »
    Où est le problème? et peut-on le réaliser directement en perl?

    Merci d'avance.

  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
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bon, je ne veux pas tester une commande aussi dangereuse.

    Mais peut-être faut-il doubler le back-slash à la fin (dont je ne sais pas trop à quoi il sert, d'ailleurs, de même que le ; qui le suit).

  3. #3
    Membre régulier

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 90
    Points : 119
    Points
    119
    Par défaut
    Cela ne change rien.

    Cependant, tout compte fait, pour une question de portabilité, je préférerai le réaliser en Perl.

    Est-ce possible ?

    Merci d'avance.

  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
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Oui, bien sûr, à mon avis c'est mieux en perl qu'en shell.

    Les fonctions opendir et readdir permettent de bien contrôler ce que l'on fait. Mais, dans beaucoup de cas, la fonction "glob /my_dir/*.*" fait aussi bien, ou mieux.

  5. #5
    Membre régulier

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 90
    Points : 119
    Points
    119
    Par défaut
    Merci.

    J'ai donc procédé de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    foreach (glob("$dir/Proj/rep1/*.*")) {
    	 unlink("$_");
    }
    foreach (glob("$dir/Proj/rep2/*.*")) {
    	 unlink("$_");
    }
    foreach (glob("$dir/Proj/rep1/sous_rep1/*.*")) {
    	 unlink("$_");
    }
    foreach (glob("$dir/Proj/rep1/sous_rep2/*.*")) {
    	 unlink("$_");
    }
    Mais au lieu de parcourir chaque dossier et sous-dossier, peut-on parcourir tout en même temps ?

  6. #6
    Membre confirmé Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Points : 515
    Points
    515
    Par défaut
    Bonjour,

    Le plus simple serait d'utiliser la fonction 'remove_tree' du package File::Path qui efface le contenu d'un répertoire de façon récursive.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    use strict;
    use warnings;
    use File::Path 'remove_tree';
     
    remove_tree("$dir/Proj/", {keep_root => 1, safe => 1}) or die "Error : $!\n\n";
    L'option keep_root permet de garder le répertoire racine et l'option safe permet de ne pas tenter de supprimer des fichiers/répertoires où l'on n'aurait pas les droits suffisants.

  7. #7
    Membre régulier

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 90
    Points : 119
    Points
    119
    Par défaut
    D'accord merci.

    Mais en considérant que mes sous-répertoires peuvent être supprimés, remove_tree va me supprimer l'ensemble des fichiers (OK) mais aussi l'ensemble des répertoires contenus dans Proj/.

  8. #8
    Membre confirmé Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Points : 515
    Points
    515
    Par défaut
    Si tu veux effectivement garder l'arborescence et ne supprimer que les fichiers, quelque chose du style en utilisant le module File::Find devrait fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    use strict;
    use warnings;
    use File::Find;
     
    find(\&delete_files, "$dir/Proj");
     
    sub delete_files {
        if (-f){
    	unlink or die "Unlink error : $!";
        }
    }
    Ici la fonction find va parcourir récursivement le ou les dossiers passé en paramètre et appliquer la fonction delete_files sur chaque fichier ou répertoire rencontré. Cette fonction teste si c'est un fichier et va le supprimer.

    Bien entendu, c'est une ébauche et il n'y a pas de vérifications des droits, pas de gestion des liens symboliques (option follow de la fonction "wanted") etc... Pour plus d'info, voir la page cpan du module

  9. #9
    Membre confirmé
    Avatar de Schmorgluck
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    371
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2006
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    Attention, Beniou, kimikou ne veut pas supprimer tous les fichiers, uniquement ceux qui contiennent un point.
    There's nothing like $HOME!

  10. #10
    Membre régulier

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 90
    Points : 119
    Points
    119
    Par défaut
    En fait, cela revient au même dans mon cas puisque tous mes fichiers contiennent un point.

    Mais effectivement, je serai intéressé de connaitre une méthode dans le cas où on voudrai supprimer des fichiers particuliers.

  11. #11
    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
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Il existe tout un tas de tests sur le type de fichier (-r -w -x -o -e -z -s -f -d -s -l -p, etc.), tu devrais trouver ton bonheur.

  12. #12
    Membre confirmé Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Points : 515
    Points
    515
    Par défaut
    Citation Envoyé par Schmorgluck
    Attention, Beniou, kimikou ne veut pas supprimer tous les fichiers, uniquement ceux qui contiennent un point
    Effectivement, kimikou cherchait des fichiers avec '*.*' mais j'avais juste lu :

    Citation Envoyé par kimikou
    J'aimerai supprimer récursivement les fichiers contenu dans Proj/
    Citation Envoyé par kimikou
    Mais effectivement, je serai intéressé de connaitre une méthode dans le cas où on voudrai supprimer des fichiers particuliers.
    Pour cela tu peux rajouter un test après le(s) test -f,etc : une expression régulière pour ne supprimer que les fichiers que tu souhaites :

    Exemple non testé : supprimer les fichiers finissant par toto*.txt (Ensuite tu peux appliquer un basename pour vraiment avoir le nom du fichier et être plus précis dans ta sélection) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sub delete_files {
        if (-f && /toto.*[.]txt$/) {
    	unlink or die "Unlink error : $!";
        }
    }

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

Discussions similaires

  1. Insertion d'une variable Perl dans une commande SHELL
    Par dubis dans le forum Programmation et administration système
    Réponses: 15
    Dernier message: 16/08/2010, 15h47
  2. Probléme commande shell dans script perl
    Par ApocalypseDuck dans le forum Langage
    Réponses: 2
    Dernier message: 08/04/2009, 17h54
  3. passer une variable perl à un commande shell
    Par titomiss dans le forum Langage
    Réponses: 1
    Dernier message: 19/02/2008, 20h07
  4. Executer commande shell depuis perl
    Par Matmal11 dans le forum Langage
    Réponses: 2
    Dernier message: 12/06/2007, 10h35
  5. Commande shell/perl...
    Par Life Hunter dans le forum Requêtes
    Réponses: 3
    Dernier message: 27/11/2005, 14h51

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