exemples de menus en script shell

Creation: 30 novemvre 2014
Mise à jour:
Version: 1.0
Author: Jean-Louis Bicquelet-Salaün
Location: http://jlbicquelet.free.fr
Copyright: (c) 2014 Jean-Louis BICQUELET-SALAÜN

présentation des menus

Cette page présente plusieurs menus console écrits en shell. Chacun d'eux présente des avantages et des inconvénients, mais ils peuvent vous servir de modèle pour votre propres menus.

menu simple avec des lettres

Ce menu affiche les options et permet de choisir parmi un lot de touche et on execute un script extérieur. On pourrait bien sur exécuter une fonction interne au script.

    MENU OF CHOICES

         L --    List backups

         B --    backup JLB
         R --    restore JLB
         O --    backup doc
         P --    restore doc

         D --    backup dev
         E --    restore dev

         Q --    QUIT (Leave this menu program)

         Entrez une lettre (parmi les choix possibles)
         puis tapez RETURN

#..........................................................................
# repertoire contennant les scripts
#..........................................................................

DIR_SCRIPTS=/usr/local/bin

#..........................................................................
# detournement de control-c grace a trap
#..........................................................................
trap "echo 'Control-C ne peut plus etre utilise' ; sleep 1 ; clear ; continue " 1 2 3

#..........................................................................
# menu
#..........................................................................
while true
do
  #..........................................................................
  # affichage
  #..........................................................................
  clear
  echo "\t MENU OF CHOICES

\t L -- \t List backups

\t B -- \t backup JLB
\t R -- \t restore JLB
\t O -- \t backup doc
\t P -- \t restore doc

\t D -- \t backup dev
\t E -- \t restore dev

\t Q -- \t QUIT (Leave this menu program)

\t Entrez une lettre (parmi les choix possibles)
\t puis tapez RETURN \c"

  #..........................................................................
  # saisie d une touche et gestion
  #..........................................................................
  read answer
  clear

  case "$answer" in
    [Ll]*) $DIR_SCRIPTS/list_backups ;;

    [Bb]*) $DIR_SCRIPTS/backup_jlb;;
    [Rr]*) >$DIR_SCRIPTS/restore_jlb;;
    [Oo]*) ;;
    [Pp]*) $DIR_SCRIPTS/restore_do;;

    [Dd]*) $DIR_SCRIPTS/backup_dev;;
    [Ee]*) $DIR_SCRIPTS/restore_dev;;

    [Qq]*)  echo "sortie du program" ; exit 0 ;;
    *)      echo "Choisissez une option affichee dans le menu:" ;;
  esac
  echo ""
  echo "tapez RETURN pour le menu"
  read dummy
done

Parmi les commentaires concernant ce script:

  1. En rouge, on trap les control programme pour interdire le CONTROL-C qui ferait sortir du script. Ce n'est pas obligatoire mais cela joute un control supplémentaire.

  2. En vert, on utilise une variable DIR_SCRIPTS qui pointe vers un répertoire de scripts. Cela permet de séparer et d'organiser les menus et les scripts.
  3. En bleu on voit la gestion minuscule/majuscule des saisies au clavier.

menu utilisant l'inversion video

Ce menu utilse des fonctions gérant l'affichage à l'aide de tput.


archive

  A  archive
  Q  quit

A) archive
R) restore
Q) quit

Please enter choice then press return

menu_choice=""
temp_file=/tmp/db.$$
trap 'rm -f $temp_file' EXIT

#----------------------------------------------------
# wait for e return key
#----------------------------------------------------
get_return()
{
  echo -e "Tapez RETURN\c"
  read x
  return 0
}

#----------------------------------------------------
# wait for a yes or no answer
#----------------------------------------------------
get_confirm()
{
  echo -e "Are you sure? \c"
  while true
  do
    read x
    case "$x" in
      o | oui | O | Oui | OUI )
        return 0;;
      n | non  | N | Non  | NON )
        echo
        echo "Cancelled"
        return 1;;
      *) echo "Please enter yes or no" ;;
    esac
  done
}

#----------------------------------------------------
# clear screen
#----------------------------------------------------
cls()
{
  tput clear
}

#----------------------------------------------------
# bold
#----------------------------------------------------
bold()
{
  tput sgr 1 0
  echo $1
  tput sgr 0 0
}

#----------------------------------------------------
# underline
#----------------------------------------------------
underline()
{
  tput sgr 0 1
  echo $1
  tput sgr 0 0
}

#----------------------------------------------------
# normal
#----------------------------------------------------
normal()
{
  tput sgr 0 0
  echo $1
}

#----------------------------------------------------
# normal
#----------------------------------------------------
choice()
{
  tput sgr 0 0
  echo "  \c"
  tput sgr 1 0
  echo "$1\c"
  tput sgr 0 0
  echo "  $2"
}

#----------------------------------------------------
# menu
#----------------------------------------------------
set_menu_choice() {

  cls
  bold "       archive            "
  normal

  choice "A" archive
  choice "Q" quit

cat << '###'

A) archive
R) restore
Q) quit


  bold  "Entrez votre choix et tapez RETUN"
###

  read menu_choice
  return
}

#--------------------------------------------------------
# fonction appelees par le menu
#--------------------------------------------------------

archive()
{
  return
}


restaure()
{
 
}

#==========================================================
# main
#==========================================================

rm -f $temp_file


clear
echo
echo

quit=n
while [ "$quit" != "y" ];
do
  set_menu_choice
  case "$menu_choice" in
    a) archive;;
    r) restaure;;
    q | Q ) quit=y;;
    *) echo "Sorry, choice not recognized";;
  esac
done

rm -f $temp_file

exit 0
  1. En rouge, on utilise un heredoc qui permet d'afficher un texte de plusieures lignes sans formatage (car le caractère qui entoure la chaine est ') jusqu'à la chaine indiquée. Le contenu de la chaine est libre. On a pris ici ### mais cela peut être EOF, EOT, ou ce que vous voulez.

    Si on utilise le caractère " le contenu du paragraphe sera interprété et les variables substituées comme-ci c'était du shell.

  2. En vert, une liste de fonction réutilisables:
    • get_return() - attente de la touche RETURN
    • get_confirm() - attent d'une réponse oui/non
    • cls() - efface l'écran
    • bold() - caratères gras
    • underline() caractères soulignés
    • normal() - affichage normal
    • choice() - affiche les choix en gras

La fonction set_menu_choice() affiche le menu. La gestion du menu a été laissé au corps du programme, mais on aurait pu créer une fonction.

menu avec sous menu

Ce menu permet d'appeler des sous-menus et de revenir au menu principal. Il reprend le principe de menu simple présenté au dessus.

-------------------------------------
        MAIN MENU
-------------------------------------

a )  menu user
b )  menu filesystem

q )  QUIT (Leave this menu program)

Please type a choiceletter (from the above choices) then press the RETURN key

-------------------------------------
        MENU OF CHOICES
-------------------------------------

a )  show the usernames only
b )  show the usernames and ID
c )  reset passwd
d )  unlock account

r )  return to previous menu
q )  QUIT (Leave this menu program)

Please type a choiceletter (from the above choices) then press the RETURN key

#! /bin/sh
##############################

scripts=/usr/local/bin
trap "echo 'Control-C cannot be used' ; sleep 1 ; clear ; continue " 1 2 3

#=========================================================================
usage()
{
cat << EOU

Usage:   mysmit [-h]

  -h    usage

  mysmit - AIX specific command regrouped in a menu
EOU

  exit
}
shortcuts()
{
cat << EOU

Shortcuts for mysmit:

  user          user management
  fs            filesystem menu

EOU

  exit
}
#=========================================================================
resetpwd()
{
if [ $# -ge 1 ] ; then
  usage
fi

lsuser -a unsuccessful_login_count $1
echo "Resetting unsuccessful login count of $1"
chsec -f /etc/security/lastlog -a "unsuccessful_login_count=0" -s $1
if [ $? -eq 0 ]
then
   echo "$1 resetted"
   lsuser -a unsuccessful_login_count $1
fi
}

#-------------------------------------------------------------------------
user_unlock()
{
 echo "Enter user name (you will have to fix the password):"
     read name
     if [ "$name" != "" ]
     then
        chuser -a unsuccessful_login_count=0 $name
        passwd $name
     else
        echo empty name
        read dummy
     fi
}

#=========================================================================
menu_user()
{
while true
do
clear
cat << "EOT"
-------------------------------------
        MENU OF CHOICES
-------------------------------------

a )  show the usernames only
b )  show the usernames and ID
c )  reset passwd
d )  unlock account

r )  return to previous menu
q )  QUIT (Leave this menu program)

Please type a choiceletter (from the above choices) then press the RETURN key

EOT

read answer
clear
case "$answer" in
[aA]*) echo "please wait ..." ;lsuser ALL |awk '{ print $1} ';;
[bB]*) lsuser ALL |awk '{ print $1 $3} ';;
[cC]*) echo "user name :"
     read name
     if [ "$name" != "" ]
     then
        resetpwd $name
     else
        echo empty name
        read dummy
     fi ;;
[dD]*) user_unlock;;
[Rr]*) menu_main  ;;
[Qq]*)  echo "Quitting the menu program" ; exit 0 ;;
*)      echo "Please choose an option which is displayed on the menu" ;;
esac
echo ""
echo "PRESS RETURN FOR THE MENU"
read dummy
done
}

#=========================================================================
#=========================================================================
menu_fs()
{
while true
do
clear
cat << "EOT"
-------------------------------------
        MENU OF CHOICES
-------------------------------------

a )  Change fs size

r )  return to previous menu
q )  QUIT (Leave this menu program)

Please type a choiceletter (from the above choices) then press the RETURN key

EOT

read answer
clear
case "$answer" in
[Aa]*)  echo "change a file system size "
        echo "filesystem name absolute path:"
        read fs
        if [ "$fs" = "" ]
        then
                echo "Listing $HOME"
                echo ""
                ls $HOME
        fi
        echo "Size followed by M or G for megabyte and gigabyte:"
        read size
        chfs -a size=$size $fs
       ;;
[Rr]*) menu_main  ;;
[Qq]*)  echo "Quitting the menu program" ; exit 0 ;;
*)      echo "Please choose an option which is displayed on the menu" ;;
esac
echo ""
echo "PRESS RETURN FOR THE MENU"
read dummy
done
}


menu_main()
{
RET=menu_main
while true
do
clear
cat << "EOT"
-------------------------------------
        MAIN MENU
-------------------------------------

a )  menu user
b )  menu filesystem

q )  QUIT (Leave this menu program)

Please type a choiceletter (from the above choices) then press the RETURN key

EOT

read answer
clear
case "$answer" in
[Aa]*) menu_user ;;
[Bb]*) menu_fs ;;
[Qq]*)  echo "Quitting the menu program" ; exit 0 ;;
*)      echo "Please choose an option which is displayed on the menu" ;;
esac
echo ""
echo "PRESS RETURN FOR THE MENU"
read dummy
done
}

#gestion des parametres
while getopts h os
do case "$o" in
    h)      usage;;
    s)      shortcuts;;
    esac
done

echo $1

# common
[ $# -ge 2 ] && usage
[ $# -eq 0 ] && menu_main

# shortcuts
[ "$1" == "user" ] && menu_user
[ "$1" == "fs" ] && menu_fs

echo "option menu not found type mysmit"