Script bash à tester

Bonsoir,

Je vous livre ici un petit script maison qui fournit un assistant d’installation/config pour plusieurs services :

  • config IP
  • DNS (local) : Bind9
  • DHCP isc-dhcp-server
  • CLOUD : Owncloud 5 + LAMP + https
  • SMTP : Postfix + LAMP ou LDAP + roudcube en https
  • IPTABLES (config de base)
  • Proxy avec Squid 3/Dansquardian/sarg
  • Coloration syntaxique shell de root + vim
  • Kvm/Virt-manager/Lxde + outils graphiques style gnome-manager iceweasel…
  • Certif autosigné avec CA

C’est le deuxième post concernant mon script mais je ne fais que suivre les conseils avisés de ricardo (modo) !
Le programme, côté utilisateurs, est présenté sous forme d’assistant. Il modifie les fichiers de conf des différents services proposés.
Mon script est destiné à Debian SQUEEZE/WHEEZY et se lance avec bash.

Sur une machine neuve ( de préférence) et avec les droits du super utilisateur :

wget http://pbb.trio.free.fr/tsgeri/SuperServeur.bsh bash SuperServeur.bsh

Bonne soirée !

Tu pourrais pas faire en sorte de remplacer MySQL par MariaDB ? Disons que c’est plus en adéquation avec le contrat social Debian :mrgreen:

Je vais faire mon chieur moi aussi : Squeeze ça fait tellement 2011, quid de Wheezy ? :wink:

Il y en a des choses à dire dans les 2600 lignes. C’est beaucoup trop pour un seul fichier. C’est impossible à maintenir.

Tu devrait déclarer tes fonctions dans un fichier séparé, créer un script par sous-assistant et garder le fichier principal pour charger les autres fichiers et gérer la navigation entre les sous parties.
Pareil les fichiers de configuration devraient être séparé c’est plus simple de s’y retrouver (et tu bénéficie de la coloration syntaxique quand tu les édite).

Quand je vois ligne 1005 (mais tu l’a fais plusieurs fois), ça :

[code]function exit_all () {
echo "
##########################################################################
Vous souhaitez :
1 - Quitter l’installation
2 - Retourner au menu principal
##########################################################################"
read Quit_install
case $Quit_install in 1) exit;;
2) clear screen ; Assistant_Debian;;
esac

while [ “$Quit_install” != “1” ] && [ “$Quit_install” != “2” ]
do
echo "Merci de taper 1 ou 2"
exit_all
done
}

exit_all[/code]
J’ai beaucoup de choses à dire :
[ul]
[li]il y a un problème d’indentation : très peut de choses sont indentées dans ton code et ça nuit gravement à la lisibilité (là en l’occurrence il y a une vraie erreur au niveau du case). D’autre part je crois que plus personne n’indente avec des tabulation, c’est très compliqué d’indenter avec des tabulation parce qu’il ne faut pas utiliser que des tabulations. Une tabulation ça n’a pas de taille fixe, en général par défaut c’est 8 colonnes, mais tu peut mettre la valeur que tu veux et bien indenter avec des tabulations ça consiste à rendre le code toujours aussi agréable à lire quelque soit la taille de la tabulation.[/li]
[li]tu utilise une fonction récursive ! Mon dieux c’est vraiment choquant ! Surtout qu’elle sert à rien.[/li]
[li]tu crée une fonction pour l’appeler tout de suite et plus jamais ensuite ça n’a pas d’intérêt[/li][/ul]

Voici comment je l’écrirais moi.

while true; do cat <<EOF ########################################################################## Vous souhaitez : 1 - Quitter l'installation 2 - Retourner au menu principal ########################################################################## EOF read Quit_install case "${Quit_install}" in 1) exit;; 2) clear screen Assistant_Debian ;; *) echo 'Merci de taper 1 ou 2' ;; esac done

Il n’y a plus de fonction, plus de récurssion, tout est indenté. On comprend bien qu’on a l’affichage d’une menu, la lecture d’une entrée utilisateur et qu’on s’attend à avoir 1 ou 2 sinon petit message et on boucle.

Tu a tendance à écrire des fonctions dans des fonctions, c’est mal aussi.

Tu as beaucoup de code qui se répète, genre ça :

echo " ############################################################################## $name nous allons, à présent, procéder au paramétrage de Bind9 ##############################################################################" sleep 1

Tu pourrais plutôt faire ça :

[code]function title () {
cat <<EOF
##############################################################################
$1
##############################################################################
EOF
[[ -z “$2” ]] || sleep “$2”
}

title “$name nous allons, à présent, procéder au paramétrage de Bind9” 1[/code]

Et ta fonction title tu l’utilise partout après.

Après il y a pleins de petites choses :
[ul][li]tes variables sont rarement protégées[/li]
[li]ça sed -i “s/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/$serial/” pourrait être avantageusement remplacé par sed -ir “s/[0-9]{10}/$serial/”[/li]
[li]je vois que dans la partie dns tu fais des sauvegardes de fichiers puis tu les restaure si besoin, c’est bien mais faut pas que tu oublie la partie restauration quand tu ajoute un fichier à sauvegarder. pour éviter ce risque tu met la liste des fichiers dans un tableau et tu itère sur ce tableau pour sauvegarder comme pour restaurer[/li]
[li]l’utilisation des tes par [[]] plutôt que [][/li][/ul]

Ça fait déjà assez de boulot je trouve.

Bonjour Syam,

Personnellement, je ne met en prod que des distro “stables” mais penses tu que j’aurais beaucoup de choses à modifier si tu a eu l’occasion de tester wheezy ?

Cordialement,

Bonjour Mimoza,

Je n’ai pas encore eu le temps de tester mariadb non plus, à vrai dire je n’en eu vent qu’il y a 2 semaines… Les commendes sont-elles exactement les mêmes du genre :

mariadb -u root -p < fichier_cmd

ou

mariadbadmin -u root --pasword=xxxxxxxxxxxx < fichier_cmd

Je vais y jeter un coup d’œil !

Cordialement,

Bonjour Mimoza,

Merci beaucoup pour ce post très détaillé, lorsque tu dis :

sed -ir “s/[0-9]{10}/$serial/”

Tu m’aides beaucoup car j’ai essayé d’implémenter ce regex mais sans succès je pense qu’il me manquait tout simplmement le r en argument pour sed !
Merci aussi pour les autres remarques, comme tu l’as dit ça va me faire du taf pour nettoyer tout ça !
En ce qui concerne les fichiers séparés, je préfère garder autant que faire se peut tout dans un seul fichier, pour l’édition, j’utilise notepad ++ (sous winbug) et je bosse dans des fichiers séparé avant de les réinjecter dans le fichier principal donc pas de soucis de coloration syntaxique. Autant je suis un fervent partisant de vim pour l’édition des fichiers, autant pour 2600 lignes je ne peux pas…
Pour les case avec un : *) la boucle est-elle infinie tant que l’utilisateur n’a pas donné une réponse correcte ? Lorsque tu dis : “tes variables sont rarement protégées” je ne comprends pas, je suis autodidacte et je galère un peu !

J’ai du taf !!!

Merci encore.

Le fait d’utiliser plusieurs fichiers n’est pas simplement pour la coloration syntaxique, c’est plus pour un soucis de “maintenabilité”. Trouver des portions de codes dans un fichier qui fait des milliers de ligne n’est pas à mon avis la chose la plus aisée à faire (pour toi comme pour ceux qui lisent ton code!).
De plus, en optimisant l’utilisation de tes fonctions comme le soulignait MisterFreeze, tu économiserais déjà un paquet de lignes.

Oui MariaDB est 100% compatible avec les commandes MySQL, c’est une volonté du créateur de MariaDB qui est le même que MySQL.
aldarone.fr/passer-de-mysql-a-mariadb/

Avec un peu plus de détail :
kb.askmonty.org/en/mariadb-vers … atibility/

Erreur de ma part c’est -ri et pas -ir

Bonjour,

J’ai commencé à revoir mon script, j’ai essayé mariadb avec le cloud et ça fonctionne correctement j’ai testé la fonction de MisterFreez (title) et c’est le top, mais pour la gestion des erreurs j’essaye de trouver comment utiliser les regex mais sans succès. Voici un script de test qui ne fonctionne pas :

echo "type an iP" read test if [ "${test}" = [0-9]{1-3}+\.[0-9]{1-3}+\.[0-9]{1-3}+\.[0-9]{1-3} ] then echo "bravo" echo "$test" else echo "try again, I meant IPV4 !" echo "test iP" read test echo $test fi

Si quelqu’un a une idée, je suis preneur.

A + et merci pour tout les gars !

Salut,
J’ai trouvé un bout de script ici: linuxjournal.com/content/val … ash-script

[code]#!/bin/bash
function valid_ip()
{
local ip=$1
local stat=1

if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
    stat=$?
fi
return $stat

}

i=0
while ((i <= 0))
do
echo "Votre IP ?"
read test
valid_ip $test
if [[ $? -eq 0 ]]; then echo OK; ((i=1)); else echo Recommencez; fi
done[/code]

Merci lol,
Je viens de trouver le même script et je suis en train de l’implémenter à l’install de squid !
Je dis bravo à l’auteur qui nous a pondu une fonction simple mais très efficace voici un exemple d’intégration qui fonctionne avec un bout de script :

[code]function valid_ip()
{
local ip=$1
local stat=1

if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/24$ ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
    stat=$?
fi
return $stat

}

echo "
#########################################################################
Tapez ici le réseau que vous souhaitez autoriser dans Squid avec le
préfixe du réseau au format xxx.xxx.xxx.xxx/xx :
#########################################################################"
read Acl_Network
valid_ip $Acl_Network
if [[ $? -eq 0 ]]; then echo good; else echo “Tapé avec les pieds ?” ; sleep 2 ; clear screen ; echo -n “Nouvel essai :” ; read Acl_Network ; fi
sed -i “s|acl localnet src 192.168.0.0/16|acl localnet src $Acl_Network|” /etc/squid/squid.conf
clear screen [/code]

Bonjour,

J’ai trouvé un moyen d’implémenter la gestion des erreurs avec une boucle ! Car la solution ci dessus ne permet pas cela (en tout cas je n’ai pas trouvé le moyen de mettre une boucle while avec un regex).
Je suis conscient que ma méthode n’est pas très élégante mais elle fonctionne. Si jamais quelqu’un a une idée d’amélioration du code je suis preneur.

[code]

anticon @IP

function testip () {
echo "tapez une adresse IP :"
read IP
}
testip
function check_ip () {
if [[ “$IP” =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] ; then echo “Vous avez saisi une @IP plausible !” ; else clear screen ; echo "Retentez votre saisie : " ; testip ; check_ip $IP ; fi
}
check_ip $IP

function testip_netw () {
echo "tapez l’adresse de votre réseau :"
read Netw
}

anticon @IP network

testip_netw
function check_ip () {
if [[ “$Netw” =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(/[1-2]{1}[0-9]{1})|(/3[0-2]{1})|(/[0-9])$ ]] ; then echo “Vous avez saisi une @IP réseau plausible !” ; else clear screen ; echo "Retentez votre saisie : " ; testip_netw ; check_ip $Netw ; fi
}
check_ip $Netw

anticon @mail

function mail_addr () {
echo "tapez l’adresse mail :"
read Email
}
mail_addr
function check_mail () {
if [[ “$Email” =~ ^[A-Za-z0-9._%±]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}$ ]] ; then echo “Bravo vous avez tapé une adresse email avec succès !” ; else clear screen ; echo "Retentez votre saisie : " ; mail_addr ; check_mail ; fi
}
check_mail $Email[/code]

Si ça peut aider certains…

Comme ça par exemple ?

[code]#!/bin/bash

#positionne la variable globale IP
function get_ip () {
read -p 'tapez une adresse IP : ’ IP
until [[ “$IP” =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] ; do
clear screen ;
echo 'Retentez votre saisie : '
read -p 'tapez une adresse IP : ’ IP
done
echo ‘Vous avez saisi une @IP plausible !’
}
get_ip

echo “IP : $?”[/code]

Merci beaucoup Mr Freeze !

A mon grand désespoir, je n’avais pas encore vu ton message et je viens d’implémenter la gestion des erreurs sur l’ensemble de mon script…

Voici néanmoins le fruit de mon travail :

[code]## anticon IP
function valid_ip()
{
local ip=$1
local stat=1

if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
    stat=$?
fi
return $stat

}
read LaVariable
valid_ip $LaVariable
if [[ $? -eq 0 ]]; then echo good; else “Tapé avec les pieds ?” ; sleep 2 ; clear screen ; echo -n “Dernière chance :” ; read LaVariable ; fi

anticon network

function valid_netw() {
local ip=$1
local stat=1

if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
    stat=$?
fi
return $stat

}
read LaVariable
valid_netw $LaVariable
if [[ $? -eq 0 ]]; then echo good; else “Tapé avec les pieds ?” ; sleep 2 ; clear screen ; echo -n “Dernière chance :” ; read LaVariable ; fi

anticon @IP

function testip () {
echo "tapez l’adresse IP :"
read IP
}
testip
function check_ip () {
if [[ “$IP” =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] ; then echo “Vous avez saisi une @IP plausible !” ; else clear screen ; echo "Retentez votre saisie : " ; testip ; check_ip $IP ; fi
}
check_ip $IP

anticon @IP network

function testip_netw () {
echo "tapez l’adresse de votre réseau :"
read Netw
}

testip_netw
function check_ip () {
if [[ “$Netw” =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])((/[1-2]{1}[0-9]{1})|(/3[0-2]{1})|(/[0-9])){1,2}$ ]] ; then echo “Vous avez saisi une @IP réseau plausible !” ; else clear screen ; echo "Retentez votre saisie : " ; testip_netw ; check_ip $Netw ; fi
}
check_ip $Netw

anticon Numéro de Port

function testNum () {
echo "
#########################################################################
Tapez ici le numéro du port que vous souhaitez ouvrir :
#########################################################################"
read Num
}
testNum
function check_Num () {
if [[ “$Num” =~ ^([0-9]){1,4}$ ]] || [[ “$Num” =~ ^[1,2,3,4,5][0-9]{1,4}$ ]] || [[ “$Num” =~ ^6([0-9]){4}$ ]] ; then echo “Vous avez saisi numéro de port plausible !” ; else clear screen ; echo "Retentez votre saisie : " ; testNum ; check_Num $Num ; fi
}
check_Num $Num

anticon @mail

function mail_addr () {
echo "tapez l’adresse mail :"
read Email
}
mail_addr
function check_mail () {
if [[ “$Email” =~ ^[A-Za-z0-9._%±]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}$ ]] ; then echo “Bravo vous avez tapé une adresse email avec succès !” ; else clear screen ; echo "Retentez votre saisie : " ; mail_addr ; check_mail $Email ; fi
}
check_mail $Email

anticon serial bind

function serial_saisie () {
echo "
###########################################################################
Tapez ici le numéro de série au format : AAAAMMJJSS où SS est le sérial.
###########################################################################"
read serial
}
serial_saisie
function check_serial () {
if [[ “$serial” =~ [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$ ]] ; then echo “Bravo vous avez tapé un numéro de série correctement interprétable par Bind9 !” ; else clear screen ; echo "Retentez votre saisie : " ; serial_saisie ; check_serial $serial; fi
}
check_serial $serial

anticon @prefixe

function testprefixe () {
echo "
tapez ici le préfixe qui définit le masque de votre sous
réseau (exemple : /24)"
read prefixe
}
testprefixe
function check_prefixe () {
if [[ “$prefixe” =~ ((/[1-2]{1}[0-9]{1})|(/3[0-2]{1})|(/[0-9]))$ ]] && [[ “$prefixe” != [???]$ ]] ; then echo “Vous avez saisi un prefixe plausible !” ; else clear screen ; echo "Retentez votre saisie : " ; testprefixe ; check_prefixe $prefixe ; fi
}
check_prefixe $prefixe

anticon domaine

function domaine_addr () {
echo "tapez votre nom de domaine :"
read mondomaine
}
domaine_addr
function check_domaine () {
if [[ “$mondomaine” =~ [A-Za-z0-9.-]+.[A-Za-z]{2,4}$ ]] ; then echo “Bravo vous avez tapé un nom de domaine avec succès !” ; else clear screen ; echo "Retentez votre saisie : " ; domaine_addr ; check_domaine $mondomaine ; fi
}
check_domaine $mondomaine

anticon octet

function testoct4 () {
echo "Tapez ici le 2ème octet de l’@IPV4 du serveur :"
read oct4
}
testoct4
function check_oct4 () {
if [[ “$oct4” =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))$ ]] ; then echo “Vous avez saisi un octet plausible !” ; else clear screen ; echo "Retentez votre saisie : " ; testoct4 ; check_oct4 $oct4 ; fi
}
check_oct4 $oct4

anticon myhostname

function myhostname_addr () {
echo "Tapez ici le nom de machine de votre serveur"
read myhostname
}
myhostname_addr
function check_myhostname () {
if [[ “$myhostname” =~ ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-][a-zA-Z0-9]).)([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$ ]] ; then echo “Bravo vous avez tapé un nom de machine avec succès !” ; else clear screen ; echo "Retentez votre saisie : " ; myhostname_addr ; check_myhostname $myhostname ; fi
}
check_myhostname $myhostname

anticon FQDN

function CLOUD_FQDN_addr () {
echo "
$name tapez le nom FQDN de la machine qui héberge le serveur de cloud :"
read CLOUD_FQDN
}
CLOUD_FQDN_addr
function check_CLOUD_FQDN () {
if [[ “$CLOUD_FQDN” =~ ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-][a-zA-Z0-9]).)([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])+[A-Za-z0-9.-]+.[A-Za-z]{2,4}$ ]] ; then echo “Bravo vous avez tapé un nom de machine avec succès !” ; else clear screen ; echo "Retentez votre saisie : " ; CLOUD_FQDN_addr ; check_CLOUD_FQDN $CLOUD_FQDN ; fi
}
check_CLOUD_FQDN $CLOUD_FQDN

anticon domaine LDIF

function domaine_addr () {
echo "Tapez le nom votre domaine au format LDIF (ex : dc=google,dc=com): "
read Domaine_LDIF
}
domaine_addr
function check_domaine () {
if [[ “$Domaine_LDIF” =~ ^dc=[A-Za-z0-9.-]+,dc=[A-Za-z]{2,4}$ ]] || [[ “$Domaine_LDIF” =~ ^dc=[A-Za-z0-9.-]+,dc=[A-Za-z0-9.-]+,dc=[A-Za-z]{2,4}$ ]] || [[ “$Domaine_LDIF” =~ ^dc=[A-Za-z0-9.-]+,dc=[A-Za-z0-9.-]+,dc=[A-Za-z0-9.-]+,dc=[A-Za-z]{2,4}$ ]] ; then echo “Bravo vous avez tapé un nom de domaine au format LDIF !” ; else clear screen ; echo "Retentez votre saisie : " ; domaine_addr ; check_domaine $Domaine_LDIF ; fi
}
check_domaine $Domaine_LDIF

anticon sous-domaine

function check_sous_domaine () {
echo -n "Tapez ici le premier sous domaine de l’organisation (ex pour le domaine grp5.info-msj.net taper : grp5) : "
read sous_domaine
}
check_sous_domaine
function check_domaine () {
if [[ “$sous_domaine” =~ [A-Za-z0-9.-]$ ]] ; then echo “Bravo vous avez tapé un nom de sous domaine correct !” ; else clear screen ; echo "Retentez votre saisie : " ; check_sous_domaine ; check_domaine $sous_domaine ; fi
}
check_domaine $sous_domaine

anticon mailsize

function testmailsize () {
echo "
###########################################################################
Tapez la taille max des fichiers joints uploades sur le serveur en Mo
(saisissez une valeure comprise entre 01 et 15. La réponse doit
impérativement comprendre 2 caractères) :
###########################################################################"
read mailsize
}
testmailsize
function check_mailsize () {
if [[ “$mailsize” =~ 1[0-5]$ ]] || [[ “$mailsize” =~ 0[0-9]$ ]] ; then echo “Vous avez saisi une taille max des fichiers joints plausible !” ; else clear screen ; echo "Retentez votre saisie : " ; testmailsize ; check_mailsize $mailsize ; fi
}
check_mailsize $mailsize

anticon passwd

function pass_confirm () {
echo "
###########################################################################
Tapez le mot de passe de l’utilisateur $contact :
###########################################################################"
read pass_user

echo "
###########################################################################
Confirmez le mot de passe de l’utilisateur $contact :
###########################################################################"
read pass_user2
}
pass_confirm
while [ “${pass_user}” != “${pass_user2}” ]
do
echo “Les mots de passe ne correspondent pas !” ; sleep 2 ; clear screen
pass_confirm
done[/code]

Les regex proposés ici sont pour la plupart issus du web mais certains sont de ma composition, je vous demande donc d’être indulgent avec moi, c’est ma première approche…
Je re-publierais une version de mon script une fois que je l’aurais suffisamment débugué (pas tant pour la pureté du code mais plus pour avoir un retour sur l’ergonomie du programme) !

A + et MERCI A TOUS :slightly_smiling:

Avant de me coucher :

function testNum () { echo " ######################################################################### Tapez ici le numéro du port que vous souhaitez ouvrir : #########################################################################" read Num } testNum function check_Num () { if [[ "$Num" =~ ^([0-9]){1,4}$ ]] || [[ "$Num" =~ ^[1,2,3,4,5][0-9]{1,4}$ ]] || [[ "$Num" =~ ^6([0-9]){4}$ ]] ; then echo "Vous avez saisi numéro de port plausible !" ; else clear screen ; echo "Retentez votre saisie : " ; testNum ; check_Num $Num ; fi } check_Num $Num
Tu test un num (en fait non c’est un port, mais bon). Utilise les techniques pour tester les nombres :

[code]#!/bin/bash

function testNum () {
read -p "Tapez ici le numéro du port que vous souhaitez ouvrir : "
until [[ “${REPLY}” =~ ^[[:digit:]]+$ && “${REPLY}” -gt 0 && “${REPLY}” -lt 65536 ]] ; do
#clear screen
echo "Retentez votre saisie : "
read -p "Tapez ici le numéro du port que vous souhaitez ouvrir : "
done
echo “Vous avez saisi numéro de port plausible !“
PORT=”$REPLY”
}

testNum

echo “port : $PORT”[/code]
C’est :
[ul]
[li]indenté[/li]
[li]plus simple[/li]
[li]plus lisible[/li]
[li]avec une seule méthode simple et pas des récursions toute pourries[/li][/ul]

Par contre de manière générale, ça sert à rien de créer une fonction pour l’appeler toute de suite après. Crée toutes tes fonctions au début du fichiers et utilise les ensuite (si tu ne veux pas les garder dans un fichier séparer). Ça rend l’algo principale plus lisible.