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

Des codes sources perlConsultez toutes les FAQ

Nombre d'auteurs : 13, nombre de questions : 59, dernière mise à jour : 27 mai 2011 

 
OuvrirSommaireTerminal

Vous avez sans doute déjà rencontré un problème d'affichage d'accents sur une console DOS.

 
Sélectionnez
#!/usr/bin/perl
use strict;
use Carp;
use warnings;

print "J'essaie d'utiliser des accents àéé\n";
print "Essayons les entrées-sorties : \n";
 
Sélectionnez
J'essaie d'utiliser des accents ÓÚÚ
Essayons les entrÚes-sorties :

Pour palier à ce désagrément, le système de gestion des encodages de Perl est excellent, puissant et pratique, mais mal compris par pas mal de gens. Pour afficher les accents correctement sur la console DOS Windows, Il faut mettre stdout avec l'encodage correct, ou utiliser l'un des modules spécialisés. chcp permet de récupérer la codepage correcte.

Premièrement, récupérons le codepage correct.

codepage DOS
Sélectionnez
my ($codepage) = (`chcp` =~ m/:\s+(\d+)/);

Encodons ensuite toutes les sorties STDOUT, STDERR et même STDIN.

 
Sélectionnez
foreach my $h ( \*STDOUT, \*STDERR, \*STDIN ) {
  binmode $h, ":encoding(cp$codepage)";
}

Je vous recommande de toujours créer vos scripts au mode utf8. Pour cela, vous devez configurer votre éditeur de texte. Exemple avec PSPAD, il vous suffit de choisir utf8 dans le menu "format". Votre script sera ainsi au format utf8. Ensuite, mettez en début de script :

 
Sélectionnez
use utf8;

Voilà, maintenant tout "print" avec accents sera correct dans votre console DOS. Voici un script qui résume les codent ci-dessus qu'on mettra dans une fonction.

 
Sélectionnez
#!/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)";
  }
}
 
Sélectionnez
J'essaie d'utiliser des accents àéé
Essayons les entrées-sorties :

C'est quand même beaucoup mieux !! Cette fonction peut être mise dans un de vos modules et appelée en début de vos scripts. Si vous ne souhaitez pas appliquer la modification d'affichage à tout STDOUT, vous pouvez toujours utiliser le module Encode.

 
Sélectionnez
#!/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");

Si vous ne souhaitez pas utiliser le module utf8, il est toujours possible d'utiliser les codes hexa corrects. Faut-il encore s'en souvenir ! Cette solution est moins propre et maintenable, mais peut toujours être utile.

Exemple de codes hexa
ü \x81 à \x85 è \x8A
é \x82 ç \x87 ï \x8B
â \x83 ê \x88 î \x8C
ä \x84 ë \x89 ... ...


Les informations de ce tableau ont été trouvées ici, ce qui nous donne :

 
Sélectionnez
#!/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";

Voilà, notez quand même que ce n'est pas très lisible :-) !!

Consultez la discussion sur le forum au sujet des accentsDiscussion sur le forum au sujet des accents.

Mis à jour le 2010-03-21  par jedai, djibril

Pour saisir un mot de passe de façon invisible sur une console DOS, linux ou unix, il y a un module Perl Term::ReadPasswordTerm::ReadPassword .
Sous windows, l'auteur du module recommande d'utiliser le module Term::ReadPassword::Win32Term::ReadPassword::Win32.

windows
Sélectionnez
#!/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;
  }
}
linux/unix
Sélectionnez
#!/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;
  }
}
Créé le 2009-06-15  par djibril

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
Progressbar.pm
Sélectionnez
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 " %3d/$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.

Pour l'utiliser, créez un script test.pl par exemple

test.pl
Sélectionnez
#!/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;
test2.pl - module CPAN Term::ProgressBar
Sélectionnez
#!/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!";

L'utilisation d'une barre de progression peut être intéressant lorsque que vous lisez un très gros fichier. Ca vous permet de voir l'avancement de la lecture du fichier. Pour faire cela, il suffit de récupérer la taille du fichier via stat afin de créer sa barre de progression, puis au fur et à mesure de la lecture du fichier, de mettre à jour la barre avec la taille courante du fichier en cours de lecture.

Exemple :

Lecture d'un fichier avec barre de progression
Sélectionnez
#!/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;
Créé le 2009-06-16  par Philou67430, djibril

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::UITerm::UI.

Voici un exemple de code nécessitant peu de lignes
Sélectionnez
#!/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";
}

On obtient le résultat suivant :

 
Sélectionnez
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

Via la méthode get_reply, vous pouvez simuler un QCM facilement et proprement. Et si vous souhaitez poser une question attendant une réponse yes or no, c'est encore plus simple avec la méthode ask_yn.

Pour en savoir plus, la documentation CPAN est à votre disposition.

Créé le 2009-10-01  par djibril

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::LongGetopt::Long. Voici un exemple de code nous permettant de taper en ligne de commande ceci :

 
Sélectionnez
perl script.pl -nom djibril -fichier "C:\repertoire\fichier.txt"
 
Sélectionnez
#!/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";
}
résultat
Sélectionnez
nom : djibril
fichier : C:\repertoire\fichier.txt

Ce module est très complet, n'hésitez pas à lire la documentation officielle. Vous pouvez créer des alias, récupérer plusieurs arguments pour une même option, etc. Voici un dernier exemple pour la route !!

 
Sélectionnez
perl script.pl -name djibril -fichier "C:\repertoire\fichier.txt" -fichier "D:\repertoire\fichier2.txt" -numero 2 -v
 
Sélectionnez
#!/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";
}
résultat
Sélectionnez
nom : djibril
numero : 2
fichiers : C:\repertoire\fichier.txt D:\repertoire\fichier2.txt
mode verbeux

NB: Notez l'importance de protéger le chemin de vos fichiers par des guillemets, surtout s'il y a des espaces. Voilà, amusez vous bien !!

Créé le 2009-10-27  par djibril
  

Les 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 © 2011 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni 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.