Scripts et variables.

Résolu/Fermé
EminoMeneko Messages postés 2434 Date d'inscription jeudi 24 janvier 2008 Statut Membre Dernière intervention 23 mai 2018 - 13 août 2008 à 15:33
EminoMeneko Messages postés 2434 Date d'inscription jeudi 24 janvier 2008 Statut Membre Dernière intervention 23 mai 2018 - 14 août 2008 à 15:43
Bonjour,

j'aurais une question à poser concernant les variables dans les shell script

en fait pour faire simple, avant d'intégrer le principe dans un autre script qui fait à peu près 300 lignes pour le moment (il en fera sûrement moins après modularisation)

En fait j'aimerais rendre possible ceci :
utiliser le paramètre du script dans une fonction de manière plus propre que la vieille feinte que j'ai imaginé.
Voici le script
#!/bin/bash

# VARIABLES
scr1=$1
scr2=$2
scr3=$3

# FONCTIONS
VerifText()
{
   echo "param 1 $1"
   echo "recup du param 1 du script ?"
   echo $1
   return 12
}

fMainScript()
{
   echo "Paramètre 1 du script : $1 feinte 1 $scr1"
   echo "Paramètre 2 du script : $2 feinte 2 $scr2"
   echo "Paramètre 3 du script : $3 feinte 3 $scr3"
   VerifText "Essai"
}

# SCRIPT
if [ $# -lt 3 ]
then
   echo "Usage : CMD \$1 \$2 \$3"
   echo $1 $2 $3
else
   fMainScript
fi

Voici la sortie
$ ./tryfuncs.sh tata titi toto
Paramètre 1 du script :  feinte 1 tata
Paramètre 2 du script :  feinte 2 titi
Paramètre 3 du script :  feinte 3 toto
param 1 Essai
recup du param 1 du script ?
Essai


N'y a t-il pas une syntaxe plus propre et/ou plus formelle ?
Merci d'avance.

3 réponses

jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 894
14 août 2008 à 15:32
Re-

Est-ce qu'un truc du genre ferait l'affaire :
jp@debian:~/tmpfs ssh$ cat foo.sh
#! /bin/bash

# DETECTION DES EDITEURS PARMI CEUX CHOISIS #
###############################################################################
# Vérification des éditeurs installés

EDITEUR=""

for name in gedit vim nano jed
do
dpkg -l "$name" | grep ii >/dev/null
if [ $? -eq 0 ]
then
        echo "$name est installé."
        EDITEUR="$EDITEUR $name"
        TABLEAU=( $EDITEUR )
else
        echo "$name n'est pas installé. Voulez-vous l'installer ? [o/N]"
        instED="N"
        read instED

        if [ "$instED" = "o" ]
        then
                echo "Installation de $name..."
                echo "Veuillez patienter..."
                echo "apt-get install $name >> $INSTLOG 2>/dev/null"
                EDITEUR="$EDITEUR $name"
                TABLEAU=( $EDITEUR )
        fi
fi
done

echo
echo "Quel éditeur voulez-vous utiliser pour éditer le fichier de configuration ?"
echo
i=1
for nom in ${TABLEAU[@]}
do echo "$i - $nom"
i=$((i+1))
done
read choix
echo
echo "L'éditeur utilisé sera ${TABLEAU[$((choix-1))]}"

jp@debian:~/tmpfs ssh$ ./foo.sh
gedit est installé.
vim est installé.
nano est installé.
Aucun paquet ne correspond à jed.
jed n'est pas installé. Voulez-vous l'installer ? [o/N]
o
Installation de jed...
Veuillez patienter...
apt-get install jed >>  2>/dev/null

Quel éditeur voulez-vous utiliser pour éditer le fichier de configuration ?

1 - gedit
2 - vim
3 - nano
4 - jed
3

L'éditeur utilisé sera nano

jp@debian:~/tmpfs ssh$
;-))
2
EminoMeneko Messages postés 2434 Date d'inscription jeudi 24 janvier 2008 Statut Membre Dernière intervention 23 mai 2018 318
14 août 2008 à 15:43
J'ai vu rien que la première ligne de la boucle for et là j'me dis mais vraiment ça se voit que j'ai l'habitude de l'utiliser... xD
j'ai encore trop la vision C/C++ de la boucle for et pourtant j'aurais du y penser.
J'ai lu le script vite fait, ça m'a l'air impeccable ! ;) En plus tu peux modifier la liste des éditeurs comme tu veux (comme dirait Richard Stallman).
Je crois que je vais devoir ajouter une ligne dans les greetings... ^^
C'est cool.
Tu pourrais me dire où trouver des infos sur les syntaxes avancées ou particulières du ShellScript parce que j'ai voulu regarder dans un PowerPoint qu'un prof nous avait donné en cours et j'ai pas trouvé grand chose. On a jamais eu la fameuse suite qu'il nous avait promit.
Les trucs genre
i=$((i+1))

ou
${TABLEAU[@]}

Si tu as des docs même en anglais je suis preneur.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 894
13 août 2008 à 16:55
Salut,

Je ne sais pas si j'ai tout bien compris ce que tu veux ;-\
[tmpfs]$ cat emino.sh
#!/bin/bash

# VARIABLES
#scr1=$1
#scr2=$2
#scr3=$3

# FONCTIONS
VerifText()
{
   echo "param 2 $2"
   echo "recup du param 1 du script ?"
   echo $1
   return 12
}

fMainScript()
{
   echo "Paramètre 1 du script : $1"
   echo "Paramètre 2 du script : $2"
   echo "Paramètre 3 du script : $3"
   VerifText $1 "Essai"
}

# SCRIPT
if [ $# -lt 3 ]
then
   echo "Usage : CMD \$1 \$2 \$3"
   echo $1 $2 $3
else
   fMainScript $1 $2 $3
fi

[tmpfs]$ ./emino.sh tata toto titi
Paramètre 1 du script : tata
Paramètre 2 du script : toto
Paramètre 3 du script : titi
param 2 Essai
recup du param 1 du script ?
tata
[tmpfs]$
;-))
0
EminoMeneko Messages postés 2434 Date d'inscription jeudi 24 janvier 2008 Statut Membre Dernière intervention 23 mai 2018 318
13 août 2008 à 18:01
Je vais l'essayer plus tard mais je ne vois pas grand chose de modifié.
Ce que je cherche c'est utiliser l'argument $1 du script dans une fonction puisque j'écris mon script dans une fonction.
En fait je suis en train d'écrire un script qui automatise l'installation de vsftpd et je veux offrir la possibilité de donner un nom de fichier en paramètre du script (liste des users virtuels) parce que c'est la seule étape où il y'a vraiment une personnalisation en dehors du script (préparer la liste des users pour conversion au format Berkeley DB)

Mais bon je suis un peu con parce que je suis en train de me dire que je peut passer mon paramètre $1 à l'appel de la fonction donc ça serait bon
genre
funcCheminFichier()
{
   echo "Sauvegarde de $1"
   cp $1 $1.bak
}

funcCheminFichier /etc/init.d/vsftpd

et à l'appel 


Normalement je diffuserais ce script plus tard pour aider les padawanz, mais bon faudra quand même avoir un minimum de connaissance donc ça fera peut-être gagner un peu de temps à certains admins... :) Oh que j'aime mon taffe ! =D

J'ai un autre souci que je soumettrais plus tard.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 894
13 août 2008 à 18:21
[...] mais je ne vois pas grand chose de modifié. [...]
parce que je suis en train de me dire que je peut passer mon paramètre $1 à l'appel de la fonction [...]


C'est exactement ce que j'ai essayé de te montrer avec mon exemple ;-))
else
   fMainScript $1 $2 $3
fi
0
EminoMeneko Messages postés 2434 Date d'inscription jeudi 24 janvier 2008 Statut Membre Dernière intervention 23 mai 2018 318 > jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020
14 août 2008 à 09:38
Ah oui OK alors merci. J'ai du avoir un moment d'égarement. Mais je me demandais s'il n'y a pas un moyen autre pour spécifier explicitement qu'on utilise un paramètre du script comme variable dans la fonction. Tampis. :)
Passons à autre chose.
Je décris plus bas mon autre problème :

Le grand script que je suis en train d'écrire a été écrit linéairement vu que j'étais bien à fond dedans et donc depuis peu j'essaie de modulariser tout ça a travers des fonctions.

Lors du script il m'arrive de vérifier la présence de paquets et sinon de proposer l'installation de celui-ci.
voici ma fonction et un appel de celle-ci :

# Vérifie la présence d'un paquet et demande s'il faut l'installer sinon.
funcVerifPaquet()
{
   dpkg -l vsftpd | grep -v grep | grep ii >/dev/null

   if [ $? -eq 0 ]
   then
      echo "Le paquet $1 est installé."
   else
      echo "Le paquet $1 n'est pas installé."
      
      # On installe donc le paquet car c'est une nécessité
      echo "Installation du paquet pour le serveur FTP vsFTPd..."
      echo "Veuillez patienter..."
      #apt-get install $1 >>$INSTLOG 2>/dev/null
   fi
}

funcVerifPaquet gedit

NB : En relisant je vois que la fonction n'est pas exactement ce qu'elle devra être. C'est une erreur de ma part vu que j'ai copié/collé et que le paquet qui m'intéresse devra obligatoirement être installé, donc je ne demande pas si on veut l'installer ou pas. La fonction devra demander si on installe ou pas. Mais bon comme au final je vais utiliser la fonction sur le paquet qui m'intéresse le plus, on demandera quand même. xD Bref je ne corrige pas ici. Aussi le # devant le apt-get install est là parce que le script est encore en phase de développement donc ce qui m'intéresse pour le moment c'est de voir que je vais bien où je veut en fonction de mes saisies lors de l'utilisation du script.

J'ai une fonction particulière pour un paquet particulier parce qu'il existe plusieurs versions du paquet et que le numéro de version est dans le nom du paquet, donc je cherche le numéro de la plus grande version disponible et je fais le reste après...
Ma fonction funcVerifPaquet est très sympathique mais j'ai un autre souci.
Lors du processus d'installation, l'utilisateur du script peut-être amené à utiliser un éditeur et je veux lui donner le choix parmi quelques éditeurs choisis. Globalement c'est la même chose que pour vérifier la présence d'un paquet à un détail près, c'est que j'utilise une variable pour l'affichage d'un menu.

Voici le code qui n'a pas encore été modularisé et qui vous permettra de comprendre :
# DETECTION DES EDITEURS PARMI CEUX CHOISIS #
###############################################################################
# Vérification des éditeurs installés
dpkg -l gedit | grep -v grep | grep ii >/dev/null
if [ $? -eq 0 ]
then
	echo "Gedit est installé."
	ED_GEDIT=1
else
   echo "Gedit n'est pas installé. Voulez-vous l'installer ? [o/N]"
   instED="N"
   read instED
   
   if [ $instED = "o" ]
   then   
      echo "Installation de Gedit..."   
      echo "Veuillez patienter..."
      #apt-get install gedit >> $INSTLOG 2>/dev/null
      ED_GEDIT=1
   fi

fi
dpkg -l vim | grep -v grep | grep ii >/dev/null
if [ $? -eq 0 ]
then
	echo "VIM est installé."
	ED_VIM=1
else
   echo "VIM n'est pas installé. Voulez-vous l'installer ? [o/N]"
   instED="N"
   read instED
   
   if [ $instED = "o" ]
   then   
      echo "Installation de VIM..."
      echo "Veuillez patienter..."
      #apt-get install gedit >> $INSTLOG 2>/dev/null
      ED_VIM=1
   fi

fi

dpkg -l nano | grep -v grep | grep ii >/dev/null
if [ $? -eq 0 ]
then
	echo "nano est installé."
	ED_NANO=1
else
   echo "nano n'est pas installé. Voulez-vous l'installer ? [o/N]"
   instED="N"
   read instED
   
   if [ $instED = "o" ]
   then   
      echo "Installation de nano..."
      echo "Veuillez patienter..."
      #apt-get install gedit >> $INSTLOG 2>/dev/null
   fi
fi

# Que faire si aucun éditeur n'est installé ?

La seule différence avec funcVerifPaquet c'est qu'il y a des variables dans la fonction mais que dans chaque cas la variable est différente. Une fois il s'agit de ED_GEDIT, une autre fois ED_VIM et encore une autre fois ED_NANO. Toujours est-il, ce code est appelé 3 fois et donc ça devient intéressant de le transformer en fonction. Juste, comment procéder pour que la bonne variable soit traitée dans l'itération correspondante à la vérification de la présence d'un éditeur ?
En principe c'est vrai que VI est installé sur toutes les machines mais je pars du principe que ça n'est pas une généralité. J'imagine que dans le cas où aucun éditeur ne serait installé et qu'aucune installation d'éditeur ne soit demandé je peux soit obliger l'installation de l'un d'eux, soit arrêter le script avec un code et un message d'erreur.

Bon, revenons à nos moutons :
Cette variable me sert à afficher ce menu.
# Menu de choix de l'éditeur
function funcMenuEd()
{
   echo "Quel éditeur voulez-vous utiliser pour éditer le fichier de configuration ?"
   if [ $ED_GEDIT -eq 1 ]
   then
      echo "g) Gedit"
   fi
   
   if [ $ED_VIM -eq 1 ]
   then
      echo "v) Vim"
   fi
   
   if [ $ED_NANO -eq 1 ]
   then
      echo "n) Nano"
   fi
}

Après, pour valider le choix c'est pas trop dur mais j'ai copié/collé le code en l'état. En tout cas cela donne quand même une idée de ce que je cherches à faire.
Cette fonction ne doit proposer que les choix valides, donc s'il n'y a que VI d'installé (ne pas confondre VI et VIM au passage, mais ici c'est un peu le cas -juste savoir que ça n'est pas tout à fait la même chose- ^^) elle ne doit afficher que :
v) Vim


Voilà, toutes ces explications pour demander comment faire pour cette histoire de variables. J'ai bien une idée mais je ne suis pas très sur du résultat.
Il s'agirait de mettre le nom de la variable en second paramètre de la fonction mais pour la rappeler et rendre l'affectation durable, comment faire ?
Par exemple :
funcVerifEd()
{
dpkg -l $1 | grep -v grep | grep ii >/dev/null
if [ $? -eq 0 ]
then
	echo "$1 est installé."
	$2=1
else
   echo "$1 n'est pas installé. Voulez-vous l'installer ? [o/N]"
   instED="N"
   read instED
   
   if [ $instED = "o" ]
   then   
      echo "Installation de $1..."
      echo "Veuillez patienter..."
      #apt-get install gedit >> $INSTLOG 2>/dev/null
      $2=1
   fi
fi
}

funcVerifEd nano ED_NANO

Sauf que là je ne crois pas que ça va bien me faire ce que je demande. Qu'en pensez vous ?
0