Script de sauvegarde

Fermé
Lartishot Messages postés 63 Date d'inscription vendredi 17 mars 2017 Statut Membre Dernière intervention 11 août 2017 - 12 mai 2017 à 17:11
Lartishot Messages postés 63 Date d'inscription vendredi 17 mars 2017 Statut Membre Dernière intervention 11 août 2017 - 18 mai 2017 à 11:47
Bonjour,

Je tiens a préciser que je suis débutant sur ce langage et dont j'ai beaucoup de mal a mis mettre donc essayé d’être le plus précis possible pour que je puisse bien comprendre.

Dans l'optique de créer un script de sauvegarde d'équipements automatique,

Je souhaite lire un fichier txt contenant des informations, sous la forme ci-dessous, pour les attribuer chacune à une variable.

-----------------------------------------------
exemple.txt :

info1:info11:info12:info13
info2:info21:info22:info23
etc...
-----------------------------------------------

Pour obtenir le résultat suivant :

$ip = info1
$port = info11
$nom_eqpmt=info12
etc...

Utiliser les variables précédemment créés pour se connecter etc sur un équipement pour faire la sauvegarde du matos et d'effectuer cette action pour chaque ligne du fichier txt (une ligne correspondant à un équipement différent).
Si quelqu'un arrive à me mettre sur la voie, se serais au top.

J'espère que j'ai été assez compréhensible sinon n'hésité pas a me poser des questions.

A voir également:

3 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 15 mai 2017 à 18:13
Salut Lartishot,

Utiliser
split()
, comme proposé par Felice_, est une façon de faire appropriée car ta structure repose sur un séparateur, à savoir
:
. Si tu as 4 champs, comme tu semblais le dire sur ton jeu de données d'exemple, il faudra rajouter la récupération de ce 4ème champ dans le code de Felice_

Autrement, on peut aussi utiliser une regexp qui offre plus de contrôle, et permet de valider le format de tes lignes, par rapport à ton exemple où il doit il avoir 4 champs par lignes, comprenant du texte non vide séparé par des
:
avec des champs non vides.

#!/usr/bin/perl

use strict;
use warnings;

my $fichier = "monFichier.txt";
open(my $descripteur, '<:encoding(UTF-8)', $fichier)
    or die "Ouverture impossible du fichier '$fichier' $!";

while (my $row = <$descripteur>) {
    chomp $row;
    if ($row =~ /^([^:]+):([^:]+):([^:]+):([^:]+)$/) {
        my ($ip, $port, $nom_eqpmt, $comment) = ($1, $2, $3, $4);
        print "J'ai récupéré ip=$ip - port=$port - ".
            "nom_eqpmt=$nom_eqpmt - comment=$comment\n";
        # faire quelque chose avec ces données
        # lancer la sauvegarde, etc.
    } else {
        print "Erreur de format, ligne : $row\n";
    }
}
print "Terminé !\n";

La regexp en ligne 12 permet à la fois de vérifier qu'il y a bien 4 champs, séparés par 3
:
, que chaque champ comporte au moins un caractère, et de capturer le contenu de ces champs dans les variables $1, $2, $3, $4 dont le contenu est ensuite passé à tes variables de travail.

Si ce format n'est pas respecté, une erreur est signalée en ligne 19.

Dal
1
Lartishot Messages postés 63 Date d'inscription vendredi 17 mars 2017 Statut Membre Dernière intervention 11 août 2017 14
Modifié le 16 mai 2017 à 14:48
Merci pour ta réponse (avec les détails qui vont avec) ! ton script a été plus facile a assimiler que celui de Felice_. J'ai réussi assez facilement a l'adapter a mon contexte.
Ne reste plus que je fasse la partie du script qui permettra, pour chaque ligne récupérer, la connexion au routeur et la récupération du fichier de sauvegarde via tftp.
0
Lartishot Messages postés 63 Date d'inscription vendredi 17 mars 2017 Statut Membre Dernière intervention 11 août 2017 14
Modifié le 16 mai 2017 à 17:09
Si je rajoute ceci en dessous du print :


# -*- Coding: utf-8 -*-

 $obj    = shift;                                                                    
 my $prompt = shift;                                                          

        $obj->raw_pty(0);                                                                  
        $obj->log_stdout(0);                                                                 
        $obj->log_file($log_file);                                                             

        unless ( $obj->spawn("/usr/bin/telnet $ip") ) {                                    
                $return = "Commande TELNET non disponible";
                return "NOK\n";
          }

        unless ( $obj->expect(15, "User Name: " )) {                                             
                 $return = "Impossible de ce connecter en TELNET";
                 return "NOK\n";
        }

        $obj->send("$login\n");

        unless ( $obj->expect(15, "Password: " )) {                                              
                $return = "Impossible de ce connecter en TELNET";
                return "NOK\n";
        }

        $obj->send("$password\n");

        unless ($obj->expect(15, "$prompt>" )) {                                                
                $return = "Prompt invalide ou mot de passe invalide";
                return NOK, $return;
        }

        return OK, $return;

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
17 mai 2017 à 10:08
Expect est parfois un peu délicat à manier, le module Expect de Perl assez complexe. Si c'est ce que tu utilises, tu ne le fais pas de la manière suggérée par les exemples de la doc : https://metacpan.org/pod/release/RGIERSIG/Expect-1.15/Expect.pod#Source_Examples

Si tu vas utiliser Telnet systématiquement, tu pourrais utiliser Net::Telnet, qui est plus simple.

https://metacpan.org/pod/release/JROGERS/Net-Telnet-3.04/lib/Net/Telnet.pm
https://metacpan.org/pod/release/JROGERS/Net-Telnet-3.04/lib/Net/Telnet.pm#EXAMPLES

Il faut bien paramétrer le prompt si tu veux que cela fonctionne.

Dal
0
Lartishot Messages postés 63 Date d'inscription vendredi 17 mars 2017 Statut Membre Dernière intervention 11 août 2017 14
17 mai 2017 à 15:39
J'ai trouvé ce bout de code aussi mais qui utilise SSH. J'arrive mieux a cerné ce code par contre par rapport a mon précédent.

#!/usr/bin/perl

use strict; 
use warnings; 
  
use Net::SSH::Expect; 
  
my $ssh = Net::SSH::Expect->new( 
  host     => '192.168.1.1', 
  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"; 
} 
0