Tester si "$1" = une IP ?

Tester si "$1" = une IP ? - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 22-05-2006 à 12:08:33    

Bonjour,
 
Je réalise un premier script shell BASH, et je cherche à tester si un paramètre est bien une adresse IP. Seulement, je n'ai aucune idée de la manière de procéder. Mon script attend en "$1" une IP, et le reste du script ne fonctionnera pas (utilisation de ping et FTP) s'il ne s'agit pas d'une adresse IP (si on entre n'importe quoi en 2nd paramètre).
 
Pour l'instant, voilà l'embryon :

Code :
  1. #! /bin/bash
  2. clear
  3. function routine(){
  4. echo "pass";
  5. };
  6. if test -n "$1"
  7. then routine;
  8. else echo "Veuillez entrer l'IP du serveur FTP";
  9. fi
  10. exit


 
Là, ça fait juste un test simple pour savoir si un paramètre est bien passé lors de l'éxécution du script.
Exemples :
- "./test" donnera "veuillez entrer l'IP du serveur FTP"
- "./test 192.168.0.1" donnera "pass"
- "./test 22" donnera aussi "pass" (mais ce sera inexploitable).
 
Je souhaiterais donc savoir comment créer une fonction qui me permette de détecter s'il s'agit bien d'un adresse IP passé en paramètre "$1".  
 
Merci.
 

Reply

Marsh Posté le 22-05-2006 à 12:08:33   

Reply

Marsh Posté le 22-05-2006 à 12:12:41    

J'y connais rien en shell mais voici mon avis.
 
Une IP, c'est une serie de 4 nombres separes par des points et dont le dernier nombre est en fait un chiffre.
C'est comme ca, AMHA, que tu peux tester tes IP.
 
/!\ NOTE /!\
 
Je parle d'IPv4


---------------
Décentralisons Internet-Bépo-Troll Bingo - "Pour adoucir le mélange, pressez trois quartiers d’orange !"
Reply

Marsh Posté le 22-05-2006 à 14:48:48    

Ouaip.... alors a mon avis 2 possibilités, ou tu trouve quelqu'un de fort en expression reguleriere etc, et il va te faire ca en une ligne.
soit tu fait une fonction pour verifier que c'est bien une IP.
dans cette fonction, a laquelle tu passe en parametre l'addresse bien sur. Puis tu recupere les 4 composants de l'ip v4 (avec un while apres un IFS="." par exemple, ou meme avec un cut -d "." -f 1 (puis 2, 3 4).
et a chaque fois tu verifie que c'est un nombre.
Bref, y a de quoi s'amuser avec une fonction bash de quelques lignes.
Sinon encore une fois, ca doit pouvoir se faire en une ligne avec en utilisant les regexpr, mais la je sais pas faire.

Reply

Marsh Posté le 22-05-2006 à 15:15:13    

l'expression régulière en une ligne existe, elle a été donné sur prog et elle doit etre sur le net...

Reply

Marsh Posté le 22-05-2006 à 15:16:36    

Reply

Marsh Posté le 22-05-2006 à 16:45:15    

Merci pour les réponses.
 
Bien, voici un résultat, qui fonctionne sous certaines machines red hat, mais pas sous la kubuntu 5.10, et je souhaiterais en connaître la cause.
 

Code :
  1. code pourri édité


 :lol:  
 
Quand vous tappez "script a.b.c.d" par exemple, il renvoit l'IP comme valide !!!
Si vous virez la boucle "for", et que vous remplacez "$octet$i" par "$octet1", il teste le premier correctement.
Mais où est le problème ?


Message édité par kwadbox le 24-05-2006 à 16:03:25
Reply

Marsh Posté le 22-05-2006 à 16:48:01    


Heu... j'ai pas tout lu dans le detail mais...
Un truc qui me choque quand meme, il sont ou les "exit" ??
Une fonction tu dois la terminer par exit 0 ou exit 1
Donc tu peux laisser les "echo" pour suivre le deroulement du truc
(ce serait plus parlant en mettant vrai ou faux) mais faux bien faire un
exit deriere en consequence !

Reply

Marsh Posté le 22-05-2006 à 17:08:06    

Je ne pense pas que cela soit nécessaire, mais j'ai effectué les modifications, et ça ne change pas les données du problème. J'en suis a me dire que c'est un pb dû à Kubuntu, et non au script. Ce soir, j'installe une OpenSuse pour tester, tiens !
 
En tout cas, une chose est sûre, je n'aime pas du tout la manière de "structurer" en shell.
On dirait que ça vient d'un autre âge.
 
Le if...fi, case...esac, etc.
 
Et la boucle for... je m'attendais à un truc style :
for (i=1,i<5,i++){ instructions }
ben... non.
 
Et tout est à l'avenant, avec les "-ge" plutôt que les conventionnels "<=", la déclaration de variable inexistante (var nombre:Number = 25), les array n'en parlons pas, etc. M'enfin, je m'énerve, là... la frustration...
 :lol:


Message édité par kwadbox le 22-05-2006 à 17:15:56
Reply

Marsh Posté le 23-05-2006 à 09:58:09    

Heu.. en fait.. tu as oublié de preciser le shell a utiliser.
la toute premiere ligne de ton script doit resembler à :
 
#!/bin/bash
 
 

Reply

Marsh Posté le 23-05-2006 à 11:20:34    

Code :
  1. function check_ip()
  2. {
  3.     # Return true if $1 is a valid IP
  4.     echo "$1" | egrep -q "^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$"
  5. }

Reply

Marsh Posté le 23-05-2006 à 11:20:34   

Reply

Marsh Posté le 23-05-2006 à 13:49:27    

M300A a écrit :

Code :
  1. function check_ip()
  2. {
  3.     # Return true if $1 is a valid IP
  4.     echo "$1" | egrep -q "^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$"
  5. }



 
je suis pas sur que ton code fonctionne car on peut se retrouver avec une adresse 352.254.998.456.  
 
si ça peut aider je l'ai fait en perl, mais ça doit pourvoir etre utilisable avec awk

Code :
  1. if ( $ip =~ /([O1]?\d\d?|2[0-4]\d|25[0-5]).([O1]?\d\d?|2[0-4]\d|25[0-5]).([O1]?\d\d?|2[0-4]\d|25[0-5]).([O1]?\d\d?|2[0-4]\d|25[0-5])/) {


 
c'est tres tres bourrin mais ça fonctionne bien ( enfin dans mes souvenirs ça fait + d'un an que je n'y ai plus touché ... )

Reply

Marsh Posté le 24-05-2006 à 16:02:16    

Merci,
 
Je ne connais pas le principe des expressions régulières, je ne sais pas comment les utiliser. J'ai donc fignolé la détection d'erreur IPv4 de manière classique (je n'ai que trés peu de bases en scripts shell), et ça fonctionne maintenant.
 
Voici le code pour celui que ça intéresse :
 

Code :
  1. #! /bin/bash
  2. # bash script for OpenSuse 10.1
  3. clear
  4. # Déclaration de variables
  5. ip=$1
  6. min_ip=1
  7. max_ip=254
  8. # Message d'indication si aucun paramètre
  9. if [ $# -ne 1 ];
  10. then
  11. echo -e "\nERREUR. Utilisation du script: `basename $0` [IP du serveur]"
  12. exit 1
  13. fi
  14. # Test pour savoir si les octets sont des caractères numériques
  15. function isNum
  16. {
  17. if [ $# = 1 ];
  18. then
  19. tmp=`expr "$1" : '\([0-9]\{1,\}\)'`
  20.  if [ "$1" = "$tmp" ];
  21.  then
  22.   echo 0
  23.  else
  24.   echo 1
  25.  fi
  26. else
  27.  echo 2
  28. fi
  29. }
  30. # Test pour savoir si les octets sont compris entre 0 et 255
  31. function minMax
  32. {
  33. if [ $# = 3 ];
  34. then
  35.  nbr=$1
  36.  min=$2
  37.  max=$3
  38.  if [ "$nbr" -ge "$min" -a "$nbr" -le "$max" ];
  39.  then
  40.   echo 0
  41.  else
  42.   echo 1
  43.  fi
  44. else
  45.  echo 2
  46. fi
  47. }
  48. # Routine de test pour la validité de l'adresse IP
  49. for i in 1 2 3 4;
  50. do
  51. octet=`echo $ip | cut -d "." -f$i`
  52. if [ `isNum $octet` -eq 0 ];
  53.  then
  54.   if [ `minMax $octet $min_ip $max_ip` -eq 0 ];
  55.   then
  56.    echo "l'octet $i [$octet] est valide."
  57.   else
  58.    echo "l'octet $i [$octet] est incorrect."
  59.    echo "Notation décimale IPv4 requise, sans adresse de réseau ni broadcast."
  60.    exit 1
  61.   fi
  62.  else
  63.   echo "L'octet $i [$octet] est incorrect."
  64.   echo "Notation décimale IPv4 requise."
  65.   exit 1
  66. fi
  67. done


 
Bon, maintenant que la vérification d'IP passé en paramètre est faite, que mon menu de choix est réalisé, il ne me reste plus que la fonction de mesure de performance réseau à scripter. Ouf, j'en vois le bout...

Reply

Marsh Posté le 24-05-2006 à 20:12:15    

witjet a écrit :

je suis pas sur que ton code fonctionne car on peut se retrouver avec une adresse 352.254.998.456.  
 
si ça peut aider je l'ai fait en perl, mais ça doit pourvoir etre utilisable avec awk

Code :
  1. if ( $ip =~ /([O1]?\d\d?|2[0-4]\d|25[0-5]).([O1]?\d\d?|2[0-4]\d|25[0-5]).([O1]?\d\d?|2[0-4]\d|25[0-5]).([O1]?\d\d?|2[0-4]\d|25[0-5])/) {


 
c'est tres tres bourrin mais ça fonctionne bien ( enfin dans mes souvenirs ça fait + d'un an que je n'y ai plus touché ... )


 
C'est exact mais bon... C'est surtout pour eviter les erreurs de frappes ;)

Reply

Marsh Posté le 31-05-2006 à 14:53:40    

J'ai eu la réponse sur un autre forum (linux), d'un gars qui visiblement maîtrise bien les expressions régulières (ça reste abscon, pour moi). Je vous en fait part, ça peut toujours intérresser du monde :
 

Code :
  1. # Test de validité IPv4 de l'adresse entrée (expression régulière)
  2. function isIPv4 {
  3. if [ $# = 1 ]
  4. then
  5.  printf $1 | grep -Eq '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-4]|2[0-4][0-9]|[01]?[1-9][0-9]?)$'
  6.  return $?
  7. else
  8.  return 2
  9. fi
  10. }
  11. isIPv4 $ip && echo "ok" || "pas ok"


 
Bonne journée.

Reply

Marsh Posté le 31-05-2006 à 15:15:52    

C'est fou quand meme ce qu'on peut faire en une ligne :D

Reply

Marsh Posté le 01-06-2006 à 07:57:44    

la meme en IPv6  :wahoo:

Reply

Marsh Posté le 01-06-2006 à 19:28:32    

elle est loin d'etre infesable ;)

Reply

Marsh Posté le 03-01-2018 à 14:46:53    

Je déterre un peu mais toujours d'actualité en 2018  et vraiment très utile.
Perso je l'utilise sous cette forme en Ksh.  
 
read $IP_CIBLE
 
if [ ! -z $IP_CIBLE ] && [[ `echo $IP_CIBLE | /usr/xpg4/bin/grep -E '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-4]|2[0-4][0-9]|[01]?[1-9][0-9]?)$'` = $IP_CIBLE ]]  
 
                then  
                echo "Format d'ip Correct"
                else echo " Format incorrect"
fi

Reply

Marsh Posté le 03-01-2018 à 15:28:03    

beau déterrage, sinon on peut aussi utiliser ipcalc avec -4 -c comme options.


---------------
Relax. Take a deep breath !
Reply

Marsh Posté le 07-01-2018 à 08:38:25    

il est inutile d'utiliser grep entre [[ alors qu'un opérateur testant les regex y est disponible !

Code :
  1. $ ip=192.168.1.12
  2. $ isIPrgx='^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-4]|2[0-4][0-9]|[01]?[1-9][0-9]?)$'
  3. $ [[ $ip =~ $isIPrgx ]] && echo "$ip is an IP" || echo "$ip is NOT an IP"

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed