Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 25/04/2007, à 09:06

Daëavelwyn

[RESOLU] BASH : problème de boucle

Bonjour,

alors voilà, je me suis coder un petit truc en bash qui log l'activité d'un system et qui renvoi le resultat dans un mail et aussi dans un fichier daté. J'arrive a un ensemble de fonctionalité qui larche bien. Il y a dans mon script une sorte de mode de configuration, qui pose des questions sur ce que je veux mettre dans le rapport

par exemple

dreport-setting -C --mail

me demande de configurer les adresses mails ou je veux recevoir le rapport

dreport-setting -C --uptime

me demande si je veux afficher l'uptime du system dans le rapport, etc...

chacune de des options fait appel à une fonction. et mon pb, c'est que si je fais :

dreport-setting -C --all

dans mon script, cette option doit exécuter toutes les fonctions les unes a la suite des autres, or n'est exécuté que la première fonction.

à force de chercher j'ai fini par trouver d'ou venait le pb, il s'agit d'une boucle while qui se trouve dans chaque function et qui permet de reposer la question si l'utilisateur a entré une mauvaise réponse.

Visiblement, lorsque j'enleve cette boucle, l'option --all fonctionne bien, mais lorsqu'une mauvaise reponse est entrée, et bien la question n'est pas reposé, et le script passe a la question suivante...

voici un extrait de la fonction mail et de la fonction uptime :

echo "$SET_MSG_MAIL_ADDRESSA"
read MainMailAddress
	CurrentMainMailAddress=`strings $CONFIG_SCRIPT_NAME | grep "ADDRESSA="`
	sed -i s/$CurrentMainMailAddress/"OPT_MAIL_ADDRESSA="$MainMailAddress""/ $CONFIG_SCRIPT_NAME
echo ""

echo "$SET_MSG_MAIL_ADDRESSCC"
read CcMailAddress
	CurrentCcMailAddress=`cat $CONFIG_SCRIPT_NAME | grep "ADDRESSCC="`
	sed -i s/"$CurrentCcMailAddress"/"OPT_MAIL_ADDRESSCC="$CcMailAddress/ $CONFIG_SCRIPT_NAME
echo ""

echo "$SET_MSG_MAIL_ADDRESSBCC"
read BccMailAddress
	CurrentBccMailAddress=`cat $CONFIG_SCRIPT_NAME | grep "ADDRESSBCC="`
	sed -i s/"$CurrentBccMailAddress"/"OPT_MAIL_ADDRESSBCC="$BccMailAddress/ $CONFIG_SCRIPT_NAME
echo ""

while [ "$error" != "false" ]
do
echo "$SET_MSG_BACKUP_SEND_REPORT"
read BackupSendReport
CurrentBackupSendReport=`cat $MAIN_SCRIPT_NAME | grep "SendReportByMail"`
	case "$BackupSendReport" in
		$SET_INPUT_MAIL ) 
			sed -i s/"$CurrentBackupSendReport"/'SendReportByMail'/ $MAIN_SCRIPT_NAME
			rm -f "*$OPT_REPORT_FILE_NAME" # only send report by mail, so delete the tmp file
			error="false"
			;;
		$SET_INPUT_FILE )
			sed -i s/"$CurrentBackupSendReport"/'#SendReportByMail'/ $MAIN_SCRIPT_NAME
			CurrentDate=`date +%d-%m-%Y`
			if [ -f $OPT_REPORT_FILE_NAME ];then #if file doesn't exist we need to create it
				 mv $OPT_REPORT_FILE_NAME $CurrentDate$OPT_REPORT_FILE_NAME #add the current date in the file name
			else echo "** report file generated **" > $OPT_REPORT_FILE_NAME
			fi
			error="false"
			;;
		$SET_INPUT_BOTH ) 
			sed -i s/"$CurrentBackupSendReport"/'SendReportByMail'/ $MAIN_SCRIPT_NAME
			CurrentDate=`date +%d-%m-%Y`
			if [ -f $OPT_REPORT_FILE_NAME ];then #if file doesn't exist we need to create it
				 mv $OPT_REPORT_FILE_NAME $CurrentDate$OPT_REPORT_FILE_NAME #add the current date in the file name
			else echo "** report file generated **" > $OPT_REPORT_FILE_NAME
			fi
			error="false"
			;;
		* )echo "$SET_MSG_ERROR_BACKUP_SEND_REPORT";;
	esac

done

while [ "$error" != "false" ]
do
echo "$SET_MSG_UPTIME"
read ServerUptime
	CurrentServerUptime=`cat $MAIN_SCRIPT_NAME | grep "ShowUptime"`
	case "$ServerUptime" in
		$SET_INPUT_YES ) sed -i s/"$CurrentServerUptime"/'ShowUptime'/ $MAIN_SCRIPT_NAME; error="false";;
		$SET_INPUT_NO ) sed -i s/"$CurrentServerUptime"/'#ShowUptime'/ $MAIN_SCRIPT_NAME; error="false";;
		* )echo "$SET_MSG_ERROR";;
	esac
done

si j'enleve la boucle while, ça fonctionne. sinon, il n'y a que la premiere boucle qui est lu

Je pense que c'est parceque j'ai mal géré le type de boucle et la logique du retour d'erreur, mais je n'arrive pas a trouver la bonne logique...

si quelqu'un avait un bon tuto ou un peu de temps pour m'aider, merci ^^

Eventuellement, je peux aussi filer l'intégralité du programme, tte façon il est sous gpl v2 donc bon smile

Dernière modification par Daëavelwyn (Le 24/05/2007, à 00:08)


La connaissance est le droit de tous, et le devoir de chacun.

Hors ligne

#2 Le 25/04/2007, à 09:45

kaworu

Re : [RESOLU] BASH : problème de boucle

Salut !
Je pense que c'est un problème de portée de variable. En bash, toutes les variables sont visible/modifiable depuis partout (sauf dans une fonction si déclarée avec local myvar="blablabla") !
Ainsi quand tu sors de la première boucle c'est parce que "$error" == "false" , mais à ce moment, $error est toujours initialisée et a toujours la même valeur !
Donc comme la condition d'entrée dans la 2ème boucle est la même que la première ( "$error" != "false" ) et que l'on a "$error" == "false" alors on rentre pas dans la boucle !
Une solution serait de prendre un autre nom de variable, mais ce que je ferai c'est à chaque fin de boucle :

unset error

de cette manière tu réinitialise la variable $error et tu peux la réutiliser pour les boucles suivante (à condition de faire le unset à chaques fin de boucle wink )

EDIT : la bible du Bash (traduite en français !) => http://abs.traduc.org/
Bonne continuation.

EDIT2 : Aïe ! Un chat mort ! Tu peux aussi remplacer ceci (si tu veux) :

cat $fichier | grep $motif

par

grep $motif $fichier

c'est plus clair, et ça ne fais pas un "Useless Use of Cat". C'est très courant de voir un cat machin | grep chose alors que souvent grep suffit. Certains on trouvé que c'est tellement courant qu'il y a un "Useless Use of Cat Awards" où la plus inutile utilisation de cat est récompensée chaque années (sisi..). Voir ici :
http://partmaps.org/era/unix/award.html

Dernière modification par kaworu (Le 25/04/2007, à 09:52)


"There are in order of increasing severity: lies, damn lies, statistics, and computer benchmarks."

Hors ligne

#3 Le 25/04/2007, à 10:04

Daëavelwyn

Re : [RESOLU] BASH : problème de boucle

ok, super, mais en fait, je ne trouve pas ma solution très élégante hmm devoir donner un code erreur (error="false") à chaque fin de test me semble un peu lourd. Donc je me penche sur une autre solution qui serait de ne reposer la question que en cas d'erreur (et donc seulement si error="true") . Donc je vois bien que je dois mettre error="true" là :

 * )echo "$SET_MSG_ERROR_BACKUP_SEND_REPORT";;

pour avoir

 * )echo "$SET_MSG_ERROR_BACKUP_SEND_REPORT";error="true";;

mais je ne vois pas comment tourner mon code pour que la question soi reposer si error="true" ....

j'en viens a me dire que c'est la structure complète de ma fonction qui est a revoir ....

Merci pour le guide bash, je vais potasser smile


La connaissance est le droit de tous, et le devoir de chacun.

Hors ligne

#4 Le 25/04/2007, à 10:19

kaworu

Re : [RESOLU] BASH : problème de boucle

Salut !
si tu veux que ça continue tant que "$error" == "true" il faut mettre dans la condition de test pour la boucle :

while [ "$error" = "true" ]; do [...] done

Une autre solution par exemple :

while true; do
    [...]
    case $var in
        a) [...] break ;;
        b) [...] break ;;
        c) [...] continue ;;
done

avec break on sort de la boucle, avec continue (ou rien du tout) on reste dedans. ça t'évite de devoir mettre une variable.

Dernière modification par kaworu (Le 25/04/2007, à 10:20)


"There are in order of increasing severity: lies, damn lies, statistics, and computer benchmarks."

Hors ligne

#5 Le 25/04/2007, à 10:39

Daëavelwyn

Re : [RESOLU] BASH : problème de boucle

wwwwwèèèèèèèèè

Marvellous kaworu !!! C'est exactement ça que je cherchais !!!

Je te remercie vraiment, tu m'évite un mal de tête certain !!

ça et dirait de tester mon script une fois que j'aurais fini ??


La connaissance est le droit de tous, et le devoir de chacun.

Hors ligne

#6 Le 26/04/2007, à 18:08

kaworu

Re : [RESOLU] BASH : problème de boucle

pourquoi pas ^^
n'hésite pas si tu as encore besoin d'aide wink


"There are in order of increasing severity: lies, damn lies, statistics, and computer benchmarks."

Hors ligne