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 17/05/2014, à 23:11

casperfr

[tuto/script] Menu Shell

Bonsoir,

depuis un petit moment je travail a la conception d'un script me permettant de faire des choix qui soit plus agréable a utilisé qu'une le couple echo / read
je vous propose une premiere ébauche de ce que j'ai fais,
en espérent avoir des retours pour me permettre de l'amélioré au mieux de l'optimisé ou meme de corrigé des choses auquel je n'aurais pas pensé,
soyez indulgent, je me suis mis a linux que depuis Février 2014 c'est donc ma premiere contribution en code (script shell),

Donc voila,
je suis partis du postulla ou il est difficile de capturer correctement les touches de directions du clavier
j'ai donc cherché a savoir pourquoi et j'ai compris que les touche spécials ne faisant pas partit de l'aphabet (clavier) renvoyais 3 caractères a la suite, c'est caractère sont envoyé a la vitesse de gestion des touches du clavier c'est a dire le plus rapide accessible,
je captures donc ces caractères
read -sN1 -t 0.0001 k1 ;  read -sN1 -t 0.0001 k2 ;  read -sN1 -t 0.0001 k3
qu'ensuite je concatène dans une varible key
key+=${k1}${k2}${k3}
j'obtient donc la valeur de la touche dans la variable key
je peut donc maintenant tester la touche dans un case
j'ai aussi fais le constat que je n'avais pas la meme valeur qui m'était renvoyé quand j'utilisais un clavier qwerty et un clavier azerty
\e[A représente la fleche vers le haut pour un clavier azerty
\e0A représente la flèche vers le haut pour un clavier querty
j'ai donc mon case :

$'\e[A'|$'\e0A') #fleche Haut
$'\e[B'|$'\e0B') #fleche Bas

un fois la touche capturer j'ai une variable (select) qui augmente ou diminue en fonction de la selection

$'\e[A'|$'\e0A') #fleche Haut select-1
((select--)) ; ((select < 1)) && ((select=1));;
$'\e[B'|$'\e0B') #fleche Bas select+1
((select++)) ; ((select > $((${#tableau[ * ]}-1)))) && ((select=$((${#tableau[ * ]}-1))));;
((select--)) ; ((select < 1)) && ((select=1));;

j'ai un test de la variable permettant de savoir si je suis tout en haut, si je rapide encore sur la fleche vers le haut je reste sur cette valeur
ou pourrait aussi bouclé en repartant d'en bas pour cela il suffit de modifier par

((select--)) ; ((select < 1)) && ((select=$((${#tableau[ * ]}-1))));;

meme chose pour la fleche vers le bas

((select++)) ; ((select > $((${#tableau[ * ]}-1)))) && ((select=$((${#tableau[ * ]}-1))));;

quand j'arrive en bas du tableau, je reste en bas, sinon on peut repartir au début pour cela

((select++)) ; ((select > $((${#tableau[ * ]}-1)))) &&((select=1));;

la variable select permet donc de savoir dans le menu qu'elle est la ligne en cour de selection
quand on fixe donc cette variable select au démarrage de l'affichage du menu cela permet de chosir la ligne du menu qui est selectionner par défaut

une fois cette selection fait,
j'utilise les couleurs pour affiché la selection
j'ai donc fait une fonction cmenu (couleur menu) qui est en faite un simple echo -e gérant les couleurs avec simplement a la fin un retour a la couleur d'origine

j'ai choisi d'utilisé les tableaux pour la liste des choix cela permet de facilité la détection de la fin du tableau pour le mettre dans les boucles
la taille max de mon tableau est donc ${#tableau[ * ]}
sachant que le tableau peut etre utilisé plusieurs fois dans un meme script il faut donc remettre a zero toutes les valeurs du tableau pour évité les valeurs 'parasites'

donc voici le code au complet
pensez a modifier tableau[ * ] en enlevant les espaces

#! /bin/bash

#couleur du menu
affselect1='\E[31;47m' #couleur rouge sur fond blanc
affselect2='\E[41;33m' #couleur jaune sur fond rouge
defaut='\E[37;40m' #couleur du shell ecriture blanche fond noir

#######echo : affichage des couleurs (surbrillance)######
function cmenu () {
 message=${1}
 couleur=${2:-$defaut} #couleur si non indique alors couleur defaut par defaut
  echo -e "$couleur $message $defaut"
  return
}

#######affichage du menu avec la selection (surbrillance)######
function affmenu () {
clear
cmenu "${tableau[0]}" $affselect2 #Titre du menu
echo
for (( i=1; i<=$((${#tableau[ * ]}-1)); i++ )) do
  if [ $i = $1 ]
    then
        cmenu "${tableau[$i]}" $affselect1
    else
        cmenu "${tableau[$i]}"
  fi
done
return
}

#######navigation du menu avec affichage du menu######
function menu () {
affmenu $select
while read -sN1 key
do
  read -sN1 -t 0.0001 k1 ;  read -sN1 -t 0.0001 k2 ;  read -sN1 -t 0.0001 k3
  key+=${k1}${k2}${k3}
  case "$key" in
    $'\e[A'|$'\e0A') #fleche Haut select-1
        ((select--)) ; ((select < 1)) && ((select=1));;
    $'\e[B'|$'\e0B') #fleche Bas select+1
        ((select++)) ; ((select > $((${#tableau[ * ]}-1)))) && ((select=$((${#tableau[ * ]}-1))));;
    q|'') #q ou entrer pour stopper
        break
  esac
affmenu $select
done
}

et voici la méthode d'utilisation

#Menu a afficher dans la console
# Exemple 4 choix de menu
select=1 #selection de la premiere valeur en surbrillance
tableau=() #remise a zero du tableau au cas de plusieurs utilisation de menu
tableau[0]="**************MENU****************" #0-Titre du menu
tableau[1]="   Choix Menu 1                   "
tableau[2]="   Choix Menu 2                   "
tableau[3]="   Choix Menu 3                   "
tableau[4]="   Choix Menu 4                   "
menu #lancement du menu
echo "Nom du menu selectionner --> " ${tableau[$select]}
echo "Numéro de la ligne correspondant au menu selectionner --> " $select

un exemple simple oui/non

select=1 #selection de la premiere valeur en surbrillance
tableau=() #remise a zero du tableau au cas de plusieurs utilisation de menu
tableau[0]="**************MENU****************" #0-Titre du menu
tableau[1]="     OUI                   "
tableau[2]="     NON                 "
menu #lancement du menu
echo "Votre selection : " ${tableau[$select]}
echo "La valeur de votre selection : " $select

autre exemple

# "Exemple d'affichage des bases de données"
#
MDP_BDD="mdp_root" #mot de passe root de la base de données
select=1
tableau=()
tableau[0]="Selection d'une base de donnees pour l'installation"
tableau[1]="Annuler"
tableau[2]="Nouvelle base de donnees"
LISTEBDD=$( echo 'show databases' | mysql -u root --password=mdp_root_de_la_base_de_donné)
j=2 #compteur pour le tableau
for BDD in $LISTEBDD
do
if [[ $BDD != "performance_schema" ]] && [[ $BDD != "information_schema" ]] && [[ $BDD != "mysql" ]] && [[ $BDD != "Database" ]] && [[ $BDD != "phpmyadmin" ]]; then
	((j++)) #+1 au tableau on commence donc la valeur a 3
	tableau[$j]=$BDD
fi
done
menu		
case $select in
	1)	exit
		;;
	2)	#creation d'un nouvelle base de donnees
		clear
		echo "Veuillez entrees le nom de la nouvelle base de donnees"
		read bdd
		Q1="CREATE DATABASE \`$bdd\`;"
		sudo mysql -u root --password=${MDP_BDD} -e "$Q1"
		;;
	*)	bdd=${tableau[$cur]}
		;;
esac
echo "Base de données selectionner $bdd"

encore un autre petit exemple

DOSSIER1="/var/www/html" #dossier d'installation pour wordpress
MDP_BDD="mdp_root" #mot de passe root de la base de données
pathcurrent=$(pwd) #emplacement du dossier actuel
select=4
tableau=()
tableau[0]="*****************MENU*******************"
tableau[1]="Installation d'un serveur LAMP          "
tableau[2]="Installation de wordpress               "
tableau[3]="Installation de samba & partage /etc/www"
tableau[3]="Installation de Webmin                  "
tableau[4]="Annuler                                 "
menu		
case $select in
	1) #Installation d'un serveur LAMP
		apt-get install -y apache2 mysql-server-5.5 php5 libapache2-mod-php5 proftpd php5-mysql phpmyadmin openssl
		a2enmod rewrite
			VAR1="127.0.1.1"
			VAR2="\127.0.1.1        $HOSTNAME.local.lan     $HOSTNAME"
		sed -i".bak" "/$VAR1/c $VAR2" /etc/hosts		
		service apache2 restart
		;;
	2) #Installation de Wordpress
		sudo wget http://fr.wordpress.org/latest-fr_FR.zip -O $DOSSIER1/latest-fr_FR.zip
		sudo unzip -o $DOSSIER1/latest-fr_FR.zip -d $DOSSIER1
		sudo mv $DOSSIER1/wordpress/* $DOSSIER1
		apt-get install -y unzip
		# Configuration automatique de Wordpress
		sudo touch $DOSSIER1/.htaccess
		sudo cat >> $DOSSIER1/.htaccess <<EOF
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
EOF
		sudo chmod 644 $DOSSIER1/.htaccess
		CONFIG=$DOSSIER1/wp-config.php
		sudo rm -rf $CONFIG
		sudo cp $DOSSIER1/wp-config-sample.php $CONFIG
		function rempl {
			sudo sed -i -e "s/.*$1.*/$2/g" $3
		}
		rempl "DB_NAME" "define('DB_NAME', '${bdd}');" $CONFIG
		rempl "DB_USER" "define('DB_USER', 'root');" $CONFIG
		rempl "DB_PASSWORD" "define('DB_PASSWORD', '${MDP_BDD}');" $CONFIG
		sudo rm -rf $DOSSIER1/keys
		sudo wget https://api.wordpress.org/secret-key/1.1/salt -O $DOSSIER1/keys
		sudo sed -i -e '/.*define.*put your unique phrase here.*/ s//EmplacementTemporaire/g' $CONFIG
		sudo sed -i -e '$!N; /^\(.*\)\n\1$/!P; D' $CONFIG
		cd $DOSSIER1
		sudo sed -i -e '/EmplacementTemporaire/ r keys' -e '//d' $CONFIG
		cd $pathcurrent
		sudo rm -rf $DOSSIER1/wordpress
		sudo rm -rf $DOSSIER1/keys
		sudo rm -rf $DOSSIER1/latest-fr_FR.zip
		;;
	3) #partage samba de /etc/www/html
		sudo apt-get -y --force-yes -f install samba
		sudo cat >> /etc/samba/smb.conf <<EOF
[${domaine}]
	force user = www-data
	force group = www-data
	comment = Partage www
	path = $DOSSIER1
	public = yes
	security = share
	writable = yes
	browseable = yes
	read only = no
EOF
		sudo service smbd restart && sudo service nmbd restart
		;;
	4) #Installation de Webmin
		mkdir /tmp/
		wget http://www.webmin.com/jcameron-key.asc -O /tmp/jcameron-key.asc
		apt-key add /tmp/jcameron-key.asc
		echo "deb http://download.webmin.com/download/repository sarge contrib " >>/etc/apt/sources.list
		apt-get update
		apt-get install -y webmin
		clear
		echo "accès a webmin https://$(ifconfig eth0 | awk -F'[: ]' '/inet ad/ {print $13}'):10000"
		;;
	*) #quit
		exit 0
		;;
esac

a cause de l'usage des tableaux ce menu ne fonctionne qu'en bash et non en sh,
si quelqu'un a une idée j'aimerais bien savoir si on peut utilisé les tableaux avec un shell sh
pour une raison que j'ignore,
a chaque fois que l'on veut utilisé tableau[ * ] et que je l'inscrit dans la fenetre du forum celle me fait une erreur il a donc fallut mettre des espaces
donc dans toutes mes explicaitons, il n'y a aucun espaces entre les [] mais c'est pour évrité les erreurs sur le forum

Hors ligne