FAQ PerlConsultez toutes les FAQ
Nombre d'auteurs : 18, nombre de questions : 250, dernière mise à jour : 29 octobre 2015 Ajouter une question
Bienvenue sur la FAQ Perl. Cette FAQ a pour vocation de vous enseigner ou de vous faire revoir les notions élémentaires de ce fantastique langage. Perl est très utilisé dans différents domaines depuis la gestion système, le réseaux, l'administration de bases de données, le web (CGI), la bureautique, la conception d'interfaces graphiques ou des contextes scientifiques telle la bioinformatique. Nous espérons que cette FAQ vous sera d'une grande utilité.
Vous souhaitez participer à l'amélioration de cette FAQ, n'hésitez pas !! Commentez
Bonne lecture !
- Comment afficher des accents sur une console Windows (DOS) ou un terminal Linux/Unix ?
- Comment saisir un mot de passe de façon invisible sur une console ?
- Comment afficher une barre de progression sur une console ?
- Comment créer une question à choix multiple dans un terminal ?
- Comment récupérer proprement les arguments de la ligne de commande ?
Vous avez sans doute déjà rencontré un problème d'affichage d'accents sur une console DOS ou un terminal Linux.
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 | #!/usr/bin/perl use strict; use Carp; use warnings; print "J'essaie d'utiliser des accents àéé\n"; print "Essayons les entrées-sorties : \n"; |
Code : | Sélectionner tout |
1 2 | J'essaie d'utiliser des accents ÓÚÚ Essayons les entrÚes-sorties : |
Premièrement, récupérons le codepage correct.
Code perl : | Sélectionner tout |
my ($codepage) = (`chcp` =~ m/:\s+(\d+)/);
Code perl : | Sélectionner tout |
1 2 3 | foreach my $h ( \*STDOUT, \*STDERR, \*STDIN ) { binmode $h, ":encoding(cp$codepage)"; } |
Code perl : | Sélectionner tout |
use utf8;
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/usr/bin/perl use strict; use Carp; use warnings; use utf8; ActiverAccentDOS(); print "J'essaie d'utiliser des accents àéé\n"; print "Essayons les entrées-sorties : \n"; sub ActiverAccentDOS { my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ ); foreach my $h ( \*STDOUT, \*STDERR, \*STDIN ) { binmode $h, ":encoding(cp$codepage)"; } } |
Code : | Sélectionner tout |
1 2 | J'essaie d'utiliser des accents àéé Essayons les entrées-sorties : |
Ce programme a tout de même un défaut, il n'est pas portable et ne fonctionnera que sous Windows. Modifions-le pour que la procédure sous fonctionnelle quelque soir l'OS.
Code perl : | Sélectionner tout |
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 | #!/usr/bin/perl use strict; use Carp; use warnings; use utf8; ActiverAccents(); print "J'essaie d'utiliser des accents àéé\n"; print "Essayons les entrées-sorties : \n"; sub ActiverAccents { my $encodage; # Windows if ( lc($^O ) eq 'mswin32') { eval { my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ ); $encodage = "cp$codepage"; foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) { binmode $h, ":encoding($encodage)"; } }; } else { $encodage = `locale charmap`; eval { foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) { binmode $h, ":encoding($encodage)"; } }; } return $encodage; } |
Si vous ne souhaitez pas appliquer la modification d'affichage à tout STDOUT, vous pouvez toujours utiliser le module Encode.
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | #!/usr/bin/perl use strict; use Carp; use warnings; use utf8; use Encode; my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ ); print encode("cp$codepage", "J'essaie d'utiliser des accents àéé\n"); print encode("cp$codepage", "Essayons les entrées-sorties : \n"); |
ü | \x81 | à | \x85 | è | \x8A |
é | \x82 | ç | \x87 | ï | \x8B |
â | \x83 | ê | \x88 | î | \x8C |
ä | \x84 | ë | \x89 | ... | ... |
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 | #!/usr/bin/perl use strict; use Carp; use warnings; print "J'essaie d'utiliser des accents \x85\x82\x82\n"; print "Essayons les entr\x82es-sorties : \n"; |
Commentez
Pour saisir un mot de passe de façon invisible sur une console DOS, linux ou unix, il y a un module Perl Term::ReadPassword .
Sous windows, l'auteur du module recommande d'utiliser le module Term::ReadPassword::Win32.
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/usr/bin/perl use strict; use warnings; use Term::ReadPassword::Win32; # Faire deviner le mot de passe : perl while (1) { my $password = read_password('Veuillez deviner le mot de passe : '); redo unless defined $password; if ($password eq 'perl') { print "Bravo, c'est le bon.\n"; last; } else { print "Dommage!\n"; redo; } } |
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/usr/bin/perl use strict; use warnings; use Term::ReadPassword; # Faire deviner le mot de passe : perl while (1) { my $password = read_password('Veuillez deviner le mot de passe : '); redo unless defined $password; if ($password eq 'perl') { print "Bravo, c'est le bon.\n"; last; } else { print "Dommage!\n"; redo; } } |
Pour afficher une barre de progression sur la console DOS, Linux ou Unix, il est possible de la créer soit même ou bien d'utiliser des modules existant. Nous allons vous donner 2 exemples.
- Code conçu soit même
Code perl : | Sélectionner tout |
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | package Progressbar; use strict; use warnings; # Constructor sub new { my $proto = shift; my %p = @_; my $class = ref($proto) || $proto; my $self = { anim => [ ref($p{anim}) eq 'ARRAY' ? @{$p{anim}} : qw(\\ | / -) ], text => $p{text} || "", max => $p{max} || 100, size => $p{size} || 40, value => $p{init} || 0, display_count => $p{verbose} || 0, animation => $p{anim} || 0, fill_char => $p{fill_char} || "#", nb_filled => 0, last_size_printed => 0, }; $self->{step} = $self->{max} / $self->{size}; bless ($self, $class); return $self; } # Progress method sub inc { my $self = shift; my $nb_filled = int(($self->{value}++) / $self->{step}) + 1; if ($self->{nb_filled} != $nb_filled || $nb_filled == $self->{size}) { my $pb = sprintf ("$self->{text} [%-$self->{size}s]", $self->{fill_char} x $nb_filled); $pb .= " ".$self->{anim}->[$nb_filled % @{$self->{anim}}] if $self->{animation}; $pb .= sprintf " =/$self->{max}", $self->{value} if $self->{display_count}; $pb .= "\r"; print STDERR $pb; $self->{last_size_printed} = length $pb; } $self->{nb_filled} = $nb_filled; } # Erase method sub erase { my $self = shift; my ($string) = @_; print STDERR (" " x $self->{last_size_printed})."\r"; print STDERR $string if defined $string; } # Reset/end method sub end { my $self = shift; $self->{value} = 0; $self->{nb_filled} = 0; print STDERR "\n"; } 1; __END__ =head1 NAME =head1 SYNOPSIS use Progressbar; my $pb = Progressbar->new(text => "Computing"); foreach (0 .. 99) { # ... $pb->inc; } $pb->erase("Process done"); $pb->end; # $pb can be re-used immediatly my $pb2 = Progressbar->new(text => "Working", anim => 1); my $pb3 = Progressbar->new(text => "Working", max => 1000, size => 58, init => 500, verbose => 1, anim => [qw(0 1 2 3 4 5 6 7 8 9)], fill_char => "="); foreach (0 .. 99) { # ... $pb2->inc; } $pb2->end; foreach (500 .. 999) { # ... $pb3->inc; } $pb3->end; =head1 DESCRIPTION Prints a progress bar on STDERR using ASCII characters. =head1 BUGS No known bug. |
Code perl : | Sélectionner tout |
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 | #!/usr/bin/perl use strict; use warnings; use lib "."; use Time::HiRes qw(sleep); use Progressbar; my $pb = Progressbar->new(text => "Computing"); foreach (0 .. 99) { sleep(rand(0.1)); $pb->inc; } $pb->erase("Process done"); $pb->end; # $pb can be re-used immediatly my $pb2 = Progressbar->new(text => "Working", anim => 1, verbose => 1); my $pb3 = Progressbar->new(text => "Working", max => 1000, size => 58, init => 500, verbose => 1, anim => [qw(0 1 2 3 4 5 6 7 8 9)], fill_char => "="); foreach (0 .. 99) { sleep(rand(0.1)); $pb2->inc; } $pb2->end; foreach (500 .. 999) { sleep(rand(0.02)); $pb3->inc; } $pb3->end; |
- Utilisation d'un module existant sur le CPAN Term::ProgressBar
Code perl : | Sélectionner tout |
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 | #!/usr/bin/perl use warnings; use strict; use Term::ProgressBar; use Time::HiRes qw(sleep); my $MaxValue = 100; my $barre_progression1 = Term::ProgressBar->new( { name => "[Computing] ", count => $MaxValue, ETA => "linear", } ); foreach (0 .. $MaxValue) { sleep(rand(0.1)); $barre_progression1->update($_); } $barre_progression1->message("Process done"); my $barre_progression2 = Term::ProgressBar->new( { name => "[Working] ", count => $MaxValue, } ); foreach (0 .. $MaxValue) { sleep(rand(0.1)); $barre_progression2->update($_); } $MaxValue = 1000; $barre_progression2->target($MaxValue); $barre_progression2->message('max: 1000'); foreach (0 .. $MaxValue) { sleep(rand(0.01)); $barre_progression2->update($_); } print "\nFini!"; |
Exemple :
Code perl : | Sélectionner tout |
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 | #!/usr/bin/perl use warnings; use strict; use Term::ProgressBar; my $file = 'mon_fichier.txt'; my $size_max = ( stat $file )[7]; my ( $compteur_modif, $progression_octet, $next_update ) = ( 0, 0, 0 ); my $barre_progression = Term::ProgressBar->new( { name => "[Lecture $file] ", count => $size_max, ETA => "linear", } ); open( my $fh, '<', $file ) or die "Impossible d'ouvrir le fichier $file\n"; while ( my $ligne = <$fh> ) { # ... <=== on travaille sur la ligne #bar $progression_octet += length($ligne); $next_update = $barre_progression->update($progression_octet) if ( $progression_octet > $next_update && $progression_octet < $size_max ); } close($fh); $barre_progression->update($size_max) if $size_max >= $next_update; |
Si vous avez besoin que l'utilisateur interagisse avec votre script, vous avez le choix de le faire via une interface graphique (Perl/Tk, gtk2, etc), ou via la console (DOS, Linux, Unix, ...).
Pour interagir via une console, on utilise généralement <STDIN>. C'est simple, mais lorsque l'on a plusieurs choix, on est obligé de faire plusieurs boucles afin de tester la validité du choix. De plus, il ne faut pas oublier de faire un chomp pour éliminer les retour chariots. Il existe une multitude de modules sur le CPAN nous facilitant grandement la vie. C'est le cas du module Term::UI.
Code perl : | Sélectionner tout |
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 | #!/usr/bin/perl use warnings; use strict; use Term::UI; use Term::ReadLine; my $term = Term::ReadLine->new('prompt'); my $reponse = $term->get_reply( prompt => 'Choisir un nombre : ', choices => [ 'Choix 1', 'Choix 2', 'Choix 3', 'Aucun choix'], default => 'Aucun choix', ); print "Vous avez choisi : $reponse\n"; my $bool = $term->ask_yn( prompt => 'Aimez vous les cookies ?', default => 'n', ); if ( $bool ) { print "J'aime les cookies\n"; } else { print "Je n'aime pas les cookies\n"; } |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | 1> Choix 1 2> Choix 2 3> Choix 3 4> Aucun choix Choisir un nombre : [4]: 7 Invalid selection, please try again: [4] 2 Vous avez choisi : Choix 2 Aimez vous les cookies ? [y/N]: y J'aime les cookies |
Pour en savoir plus, la documentation CPAN est à votre disposition.
Lorsque vous souhaitez appeler vos scripts perl via une console DOS ou Linux (ou Unix), vous avez souvent besoin de passer des arguments. La manière classique pour les récupérer est d'utiliser la variable @ARGV. Sachez qu'il existe un module perl nous permettant de gérer ces arguments proprement et facilement. Ce module est de plus déjà installé dans le core de perl, c'est le module Getopt::Long. Voici un exemple de code nous permettant de taper en ligne de commande ceci :
Code : | Sélectionner tout |
perl script.pl -nom djibril -fichier "C:\repertoire\fichier.txt"
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/usr/bin/perl use strict; use warnings; use Getopt::Long; my ( $nom, $fichier ) = (); GetOptions( 'nom=s' => \$nom, 'fichier=s' => \$fichier,); if ( defined $nom ) { print "nom : $nom\n"; } if ( defined $fichier ) { print "fichier : $fichier\n"; } |
Code : | Sélectionner tout |
1 2 | nom : djibril fichier : C:\repertoire\fichier.txt |
Code : | Sélectionner tout |
perl script.pl -name djibril -fichier "C:\repertoire\fichier.txt" -fichier "D:\repertoire\fichier2.txt" -numero 2 -v
Code perl : | Sélectionner tout |
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 | #!/usr/bin/perl use strict; use warnings; use Getopt::Long; my ( $nom, @fichiers, $numero, $verbeux) = (); GetOptions( 'nom|name=s' => \$nom, # name ou nom 'fichier=s' => \@fichiers, # On peut avoir plusieurs fichiers 'numero=i' => \$numero, # i pour integer => on récupère un entier 'verbeux|v' => \$verbeux, # flag de type -v ou -verbeux ou --v ou --verbeux ); if ( defined $nom ) { print "nom : $nom\n"; } if ( defined $numero ) { print "numero : $numero\n"; } if ( @fichiers ) { print "fichiers : @fichiers\n"; } if ( $verbeux ) { print "mode verbeux\n"; } |
Code : | Sélectionner tout |
1 2 3 4 | nom : djibril numero : 2 fichiers : C:\repertoire\fichier.txt D:\repertoire\fichier2.txt mode verbeux |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.