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 connaitre le nom et l'ip d'une machine en perl ?
- Comment connaitre le pid du script perl en cours ?
- Comment connaitre le système d'exploitation de ma machine ?
- Comment déterminer l'espace des disques ?
- Comment lancer des commandes sur un serveur distant depuis Windows ?
- Comment se connecter via SSH sur des périphériques CISCO ?
Pas de secret, le CPAN contient ce qu'il faut. Utilisez les modules Sys::Hostname et Socket déjà présent dans le CORE de perl.
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | #!/usr/bin/perl use strict; use warnings; use Sys::Hostname; use Socket; my $host = hostname; my $IP = inet_ntoa(inet_aton(hostname())); print "Ma machine $host a pour adresse IP : $IP\n"; |
Pour connaitre le pid du script perl en cours, il suffit d'utiliser la variable spéciale perl $$. Ainsi, faite ceci :
Code perl : | Sélectionner tout |
1 2 3 4 5 | #!/usr/bin/perl use strict; use warnings; print "mon pid : $$\n"; |
Vous pouvez soit afficher une variable spéciale perl $^O ou bien afficher le contenu de la variable d'environnement %ENV. Voici un exemple de script affichant les deux façon d'obtenir le résultat voulu.
Code perl : | Sélectionner tout |
1 2 3 4 5 | #!/usr/bin/perl use strict; use warnings; my $sys_expl = $^O; print "Voici mon OS : $sys_expl\n"; # => Voici mon OS : MSwin32 |
Code : | Sélectionner tout |
1 2 3 | sous Windows : mMSwin32 sous Linux : linux sous MAC : darwin |
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | #!/usr/bin/perl use strict; use warnings; #Pour information foreach my $nom_cle (keys %ENV) { print "$nom_cle : $ENV{$nom_cle}\n"; } # En ce qui nous interesse print "Voici mon OS : $ENV{OS}\n"; # Voici mon OS : Windows_NT |
Pour connaitre l'espace disque restant du C:/, D:/ ou sous linux du /, ... Il existe un module Perl, Filesys::DfPortable.
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/usr/bin/perl use strict; use warnings; use Filesys::DfPortable; my $Disque = 'C:/'; # ou même / par exemple my $ref = dfportable($Disque); if( defined($ref) ) { print"Total bytes: $ref->{blocks}\n"; print"Total bytes free: $ref->{bfree}\n"; print"Total bytes avail to me: $ref->{bavail}\n"; print"Total bytes used: $ref->{bused}\n"; print"Percent full: $ref->{per}\n" } |
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!/usr/bin/perl use strict; use warnings; use Filesys::DfPortable; my $Disque = 'C:/'; # ou même / par exemple my $FormatSortie = 1024*1024*1024; my $ref = dfportable($Disque, $FormatSortie); if( defined($ref) ) { print"Total bytes: $ref->{blocks}\n"; print"Total bytes free: $ref->{bfree}\n"; print"Total bytes avail to me: $ref->{bavail}\n"; print"Total bytes used: $ref->{bused}\n"; print"Percent full: $ref->{per}\n" } # Le résultat sera en Go. |
Il peut être intéressant de se connecter sur un serveur distant Linux afin de lancer des commandes telles (ls, perl toto.pl, etc) depuis un PC Windows. De plus, l'idéal serait de transférer des fichiers depuis son PC Windows vers un autre serveur ou l'inverse. Il est possible de faire cela depuis un script Perl sans avoir besoin d'avoir cygwin, putty…
Voici une procédure utilisant le module Net::SSH2.
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 | #!/usr/bin/perl use strict; use warnings; #======================================================== # But : Connection SSH + commandes (scp ou autre) # Args : Référence d'un hash # Retourne : rien # Besoin : modules Net::SSH2 #========================== my %InfoSSH = ( host => "IP serveur ou Host serveur", login => "login", password => "xxxxxx", cmd => ["perl /home/toto/test.pl", "ls /usr"], scp_put => [ [ "Fichier local", "Fichier destination"], [ "Fichier local"], # Depot dans le rep courant du user ], scp_get => [ [ "Fichier destination", "Fichier local"], [ "Fichier destination"], # Depot dans le rep local courant ], verbose => 1, # ou 0 ); CommandSSHFromWindows( \%InfoSSH); sub CommandSSHFromWindows { my ($RefDataConnection) = @_; $|++; # parameters my $host = $RefDataConnection->{host}; my $login = $RefDataConnection->{login}; my $password = $RefDataConnection->{password}; my $Refcmd = $RefDataConnection->{cmd}; my $Verbose = $RefDataConnection->{verbose} || 0; require File::Basename; require Net::SSH2; my $ssh2 = Net::SSH2->new(); $ssh2->connect($host); my ( $code, $error_name, $error_string ) = $ssh2->error(); if ($code) { print "[WARNING] Unable to connect to host : $host\n\n"; return; } unless ( $ssh2->auth_password( $login, $password ) ) { $ssh2->disconnect(); print "[WARNING] Unable to login.\n" . "Check your login ($login) or your password\n\n"; return; } # Lancement des commandes foreach my $cmd ( @{$Refcmd} ) { if ( $Verbose == 1 ) { print "\n- Commande [$cmd]\n"; } my $channel = $ssh2->channel(); $channel->blocking(1); $channel->exec($cmd); while ( $channel->read( my $buffer, 1024 ) ) { if ( $Verbose == 1 ) { print $buffer; } } $channel->close; } # SCP si necessaire # Put if ( exists $RefDataConnection->{scp_put} ) { foreach my $RefCoupleSCP_put ( @{ $RefDataConnection->{scp_put} } ) { unless ( -e $RefCoupleSCP_put->[0] ) { print "\n$RefCoupleSCP_put->[0] n'existe pas \n"; next; } my $message = "Transfert de $RefCoupleSCP_put->[0] vers $host"; if ( $Verbose == 1 ) { print "\n$message ... "; } $ssh2->scp_put( $RefCoupleSCP_put->[0], $RefCoupleSCP_put->[1] ) or die $ssh2->error(); print "fini\n" if ( $Verbose == 1 ); } } # Get if ( exists $RefDataConnection->{scp_get} ) { foreach my $RefCoupleSCP_get ( @{ $RefDataConnection->{scp_get} } ) { my $NomFichier = File::Basename::basename( $RefCoupleSCP_get->[0] ); if ( $Verbose == 1 ) { } $ssh2->scp_get( $RefCoupleSCP_get->[0], $RefCoupleSCP_get->[1] ) or die $ssh2->error(); print " : fini\n" if ( $Verbose == 1 ); } } $ssh2->disconnect(); return; } |
Si vous souhaitez envoyer un ou plusieurs fichiers sur le serveur distant, rajoutez dans le hachage la clé scp_put et/ou scp_get, exemple
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 | scp_put => [ # Fichier local # fichier distant [ "C:/Rep/path/monfichier sur mon disque", "/home/user/toto"], [ "C:/Rep/path/monfichier2 sur mon disque"], [ "C:/Rep/path/monfichier3 sur mon disque", "/home/user/monfichier3"], #... ], |
Ayant eu le problème moi même et constatant que c'est un problème récurrent sur Internet dont on ne trouve pas de vrais solutions, je vous propose la mienne. Pour SSH sur les périphériques Cisco beaucoup utilisent les modules Net::SSH::Perl, Perl::SSH2, voir même Net::Appliance::session et aboutissent à des problèmes sur les périphériques Cisco du genre :
- Connexion SSH impossible
- Passage Enable impossible
- Impossible de lancer plusieurs commandes dans la même session ...
Donc après avoir tout essayé, je suis tombé sur le module Net::SSH::Expect qui m'a permis d'obtenir une solution fonctionnelle en s'affranchissant des problèmes liés aux autres modules.
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 | #!/usr/bin/perl use strict; use warnings; use Net::SSH::Expect; my $ssh = Net::SSH::Expect->new( host => '192.168.90.100', password => 'cisco', user => 'admin', raw_pty => 1 ); my $enable_passwd = "cisco"; my $login_output = $ssh->login(); $ssh->send("enable"); $ssh->waitfor( 'Password:\s*\z', 1 ) or die "prompt 'password' not found after 1 second"; $ssh->send($enable_passwd); my $ls = $ssh->exec("show vlan"); print "$ls\n"; #Première façon de récupérer une sortie longue: $ssh->send("show running-config"); while ( my $line = $ssh->read_line() ) { print "$line\n"; } #Deuxième façon (mais on récupère aussi les prompt avec cette méthode): my @output = $ssh->exec("show running-config"); print @output; $ssh->close(); |
Code perl : | Sélectionner tout |
$ssh->exec("terminal length 0");
Code perl : | Sélectionner tout |
$ssh->exec("terminal length 24");
Voilà, si vous avez des questions, des remarques ou suggestions, c'est ici.
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.