Barre de chargement whiptail avec Multi scripts bash/expect

Bonjour à tous,

Je viens vers vous aujourd’hui avec une petite question concernant la gestion des processus (plus particulièrement un script expect) et leur état d’avancement.

Je vous explique, je monte actuellement une plateforme de test (pour de la formation), permettant de simuler des pannes réseaux. Pour simuler ces pannes (sur des équipement réels) j’utilise deux scripts. Un premier avec un menu (sous whiptail ~ dialog) permettant d’appeler un second script qui se connecte sur le routeur et modifie sa configuration.

Le second, le plus important, fonctionne parfaitement mais j’ai du en faire un script expect et non bash (#!/usr/bin/expect).

Le premier utilisant Whiptail pour les menus est en bash (#!/bin/bash), le menu se lance mais je souhaite ajouter en plus une barre de chargement le temps que mon script de configuration s’exécute. Pour cela j’utilise l’option “whiptail --gauge”. Si je fais une barre de chargement basée sur une estimation du temps d’exécution de mon second script (boucle avec variable qui s’incrémente) pas de soucis. Mais je n’aime pas trop cette méthode (j’ai l’impression de tricher), je souhaite plutôt obtenir l’état d’avancement du script (basée sur le numéro de la ligne en cours d’exécution par exemple).

Et c’est là que les problèmes commencent… J’ai fais pas mal de recherches pour finir par me perdre dans les méandres d’internet. Certains conseillés l’utilisation de lsof pour récupérer l’offset du fichier (avec un filtre en sortie) mais cette valeur reste à zéro pour mon script exepct (alors qu’elle évolue sur un srcipt bash). Ce n’est donc peut être pas la bonne méthode.

Voilà ma question (enfin!), comment faire ? Mais comment ?!!
Si quelqu’un à une idée pour récupérer l’état d’avancement de l’exécution du second script pour le récupérer dans le premier et le combiner avec whiptail pour en faire une barre de chargement (en pourcentage), je suis preneur :slightly_smiling:

Je sais qu’il y a pas une grande utilité à çela, mais j’ai vraiment envie de savoir. Il y a forcement un moyen.

Merci d’avance,

Pour Info : je suis un débutant! Si vous avez des conseils et des réflexions à faire sur mes scripts en général, je suis à votre écoute.

Quelques liens intéressants :
stackoverflow.com/questions/2380 … ell-script <== C’est ici que l’on parle de lsof (2eme ou 3eme réponse)
en.wikibooks.org/wiki/Bash_Shell … g/Whiptail <== Whiptail et quelques exemples

Et voilà mes scripts :

Script 1 "menu.sh" :
#!/bin/bash

#supression du fichier temporaire contenant le choix du premier menu
if [[ -d choixmenu ]]; then "rm choixmenu"; fi

whiptail --title "Script menu" --menu "faites votre choix :" 12 60 3 \
		1 "Premier TP" \
		2 "Choix 2" \
		3 "Choix 3" 2> choixmenu
#on recupere ce choix
choix=`cat ./choixmenu`

# case : action en fonction du choix, le deuxieme et le troisieme sont inutile pour le moment
case $choix in
	#c'est ici que le problème commence, on cherche à faire une barre de chargement avec l outil Whiptail
#en fonction du niveau d'execution du second script ./connexion
	"1") ./connexion.sh > connexion.log |
		{
		i=0
		while (true)
		do
		#pour le moment le script ne fonctionne que sur une base de temps (max 10 secondes), ce n'est pas ce que lon recherche
		proc=`ps -A | grep connexion.sh`
		if [[ $proc == "" ]]; then break; fi
		echo $i
		i=$(($i+10))
		sleep 1
		done
		sleep 5
	} | whiptail --title "chargement" --gauge "chargement en cours" 12 60 0
	;;
	"2") echo "choix2";;
	"3") echo "choix3";;
esac

exit 0
    Script 2 "connexion.sh"
#!/usr/bin/expect -f

spawn ssh admin@192.168.1.2

expect "password : \r"
send -- "MonPassword\r"
expect "#"
send -- "show version"
send -- "conf t"
expect "#"
interact

connexion.txt (169 Bytes)
menu.txt (1.01 KB)

J’ai la solution, je vous la donne, ça peut intéresser quelqu’un.

Pour faire la barre de chargement basée sur l’exécution des commandes et non un temps pré-determiné, il faut activer un debug au début du script expect (second script):

#!/usr/bin/expect -c strace 1

Ensuite pour avoir le calcul en pourcentage, on ajoute dans le premier script :

nombre max de ligne du second script, moins le SHABANG, multiplié par deux car le debug ajoute une ligne vide entre chaque commande executée

maxl=$(((cat connexion.sh | wc -l-1)*2))

on execute le second script qui active un debug (voir connexion.sh) permettant de savoir en temps réel quel instruction est executee, cette instruction est envoyee dans la sortie d’erreur que l’on redirige vers un fichier
./connexion.sh 2> etatprocess

#Calcul du pourcentage d’execution du script
percent=$((((cat etatprocess | wc -l)*100)/$maxl))
echo $percent

Premier script :

[code]#!/bin/bash

#supression du fichier temporaire contenant le choix du premier menu
if [[ -d choixmenu ]]; then “rm choixmenu”; fi

whiptail --title “Script menu” --menu “faites votre choix :” 12 60 3
1 “Premier TP”
2 “Choix 2”
3 “Choix 3” 2> choixmenu
#on recupere ce choix
choix=cat ./choixmenu

case : action en fonction du choix, le deuxieme et le troisieme sont inutile pour le moment

case $choix in
"1") #on calcul le nombre max de ligne dans le second script, moins le SHABANG puis on multiplie par 2 car lors du debug en temps réel du script il y a une ligne vide entre chaque instruction
maxl=$(((cat com7i.sh | wc -l-1)*2))
{
#on execute le second script qui active un debug (voir connexion.sh) permettant de savoir en temps réel quel instruction est executee, cette instruction est envoyee dans la sortie d’erreur que l on redirige vers un fichier
./connexion.sh 2> etatprocess |
while (true)
do
#Calcul du pourcentage d’execution du script
percent=$((((cat etatprocess | wc -l)*100)/$maxl))
echo $percent
#Si le processus n’apparait plus on casse la boucle
if [[ ps -A | grep com7i.sh == “” ]]; then break; fi
done
sleep 2
} | whiptail --gauge “Please wait” 12 60 0
;;
“2”) echo “choix2”;;
“3”) echo “choix3”;;
esac

exit 0
[/code]

Second script :

#!/usr/bin/expect -c strace 1
spawn ssh user@192.168.1.1
expect "user@192.168.1.1's password: $"
send -- "Password\n"
sleep 2
expect "user@equipment>"
sleep 2
send -- "sh ver\n"
expect "user@equipment>"
sleep 2
send -- "sh ver\n"
expect "user@equipment>"
send -- "exit"
sleep 2
exit 0


Le résultat :
Une barre de chargement qui va de 0 à 100 en fonction de l’état d’avancement du second script.

Le soucis de la solution : plus difficile à faire si on commente le fichier et il ne faut pas mettre d’espace entre chaque ligne. Mais on doit pouvoir traiter ça de manière automatique.
L’option de debug présente ici existe seulement avec expect, mais on doit avoir une option comparable en bash.