33.6. Coloriser des scripts

Les séquences d'échappement d'ANSI [102] permettent de régler les attributs de l'écran, tels que le texte en gras et la couleur d'affichage et de fond. Les fichiers batch DOS utilisaient communément les séquences d'échappement ANSI pour les affichages couleur, comme peuvent le faire les scripts Bash.

Exemple 33.11. Une base de données d'adresses « colorisée »

#!/bin/bash
# ex30a.sh : Version "colorisée" de ex30.sh.
#            Base de données d'adresses.


clear                                   # Efface l'écran.

echo -n "          "
echo -e '\E[37;44m'"\033[1mListe de contacts\033[0m"
                                        # Blanc sur fond bleu
echo; echo
echo -e "\033[1mChoisissez une des personnes suivantes :\033[0m"
                                        # Bold
tput sgr0
echo "(Entrez seulement les premières lettres du nom)"
echo
echo -en '\E[47;34m'"\033[1mE\033[0m"   # Bleu
tput sgr0                               #  Réinitialise les couleurs à la
                                        #+ "normale."
echo "vans, Roland"                     # "[E]vans, Roland"
echo -en '\E[47;35m'"\033[1mJ\033[0m"   # Magenta
tput sgr0
echo "ones, Mildred"
echo -en '\E[47;32m'"\033[1mS\033[0m"   # Vert
tput sgr0
echo "mith, Julie"
echo -en '\E[47;31m'"\033[1mZ\033[0m"   # Rouge
tput sgr0
echo "ane, Morris"
echo

read personne

case "$personne" in
# Notez que la variable est entre guillemets.

  "E" | "e" )
  # Accepte une entrée en majuscule ou minuscule.
  echo
  echo "Roland Evans"
  echo "4321 Floppy Dr."
  echo "Hardscrabble, CO 80753"
  echo "(303) 734-9874"
  echo "(303) 734-9892 fax"
  echo "revans@zzy.net"
  echo "Business partner & old friend"
  ;;

  "J" | "j" )
  echo
  echo "Mildred Jones"
  echo "249 E. 7th St., Apt. 19"
  echo "New York, NY 10009"
  echo "(212) 533-2814"
  echo "(212) 533-9972 fax"
  echo "milliej@loisaida.com"
  echo "Girlfriend"
  echo "Birthday: Feb. 11"
  ;;

# Ajoutez de l'info pour Smith & Zane plus tard.

          * )
   # Option par défaut.   
   # Une entrée vide (en appuyant uniquement sur RETURN) vient ici aussi.
   echo
   echo "Pas encore dans la base de données."
  ;;

esac

tput sgr0                               #  Réinitialisation des couleurs à la
                                        #+ "normale".

echo

exit 0

Exemple 33.12. Dessiner une boîte

#!/bin/bash
# Draw-box.sh : Dessine une boîte en utilisant des caractères ASCII.

#  Script de Stefano Palmeri, avec quelques modifications mineures par 
#+ l'auteur de ce document.
#  Modifications mineures suggérées par Jim Angstadt.
#  Utilisé dans le guide ABS avec sa permission.


######################################################################
###  doc de la fonction dessine_une_boite  ###

#  La fonction "dessine_une_boite" permet à l'utilisateur de dessiner une boîte
#+ dans un terminal.
#
#  Usage : dessine_une_boite LIGNE COLONNE HAUTEUR LARGEUR [COULEUR]
#  LIGNE et COLONNE représente la position de l'angle gauche en haut pour la
#+ boîte que vous dessinez.
#  LIGNE et COLONNE doivent être supérieurs à 0 et inférieurs aux dimensions
#+ actuelles du terminal.
#  HAUTEUR est le nombre de lignes de la boîte et doit être positif. 
#  HAUTEUR + LIGNE doit être inférieur à la hauteur actuelle du terminal. 
#  LARGEUR est le nombre de colonnes de la boîte et doit être positif.
#  LARGEUR + COLONNE doit être inférieur ou égale à la largeur actuelle du
#+ terminal.
#
# C'est-à-dire que si la dimension de votre terminal est de 20x80,
#  dessine_une_boite 2 3 10 45 est bon
#  dessine_une_boite 2 3 19 45 n'a pas une bonne HAUTEUR (19+2 > 20)
#  dessine_une_boite 2 3 18 78 n'a pas une bonne LARGEUR (78+3 > 80)
#
#  COULEUR est la couleur du cadre de la boîte.
#  Ce cinquième argument est optionnel.
#  0=noir 1=rouge 2=vert 3=tan 4=bleu 5=violet 6=cyan 7=blanc.
#  Si vous passez de mauvais arguments à la fonction,
#+ elle quittera avec le code 65
#+ et aucun message ne sera affiché sur stderr.
#
#  Effacez le terminal avant de dessiner une boîte.
#  La commande clear n'est pas contenue dans la fonction.
#  Cela permet à l'utilisateur de dessiner plusieurs boîtes, y compris en les
#  entre-mêlant.

###  fin de la doc sur la fonction dessine_une_boite  ### 
######################################################################

dessine_une_boite(){

#=============#
HORZ="-"
VERT="|"
CARACTERE_DU_COIN="+"

MINARGS=4
E_MAUVAISARGS=65
#=============#


if [ $# -lt "$MINARGS" ]; then       # Si moins de quatre arguments, quitte.
    exit $E_MAUVAISARGS
fi

# Recherche de caractères non numériques dans les arguments.
# Cela pourrait être mieux fait (exercice pour le lecteur ?).
if echo $@ | tr -d [:blank:] | tr -d [:digit:] | grep . &> /dev/null; then
   exit $E_MAUVAISARGS
fi

HAUTEUR_BOITE=`expr $3 - 1`   #  -1, correction nécessaire car le caractère
                              #+ de l'angle, "+", fait partie à la fois de
LARGEUR_BOITE=`expr $4 - 1`   #+ la hauteur et de la largeur.
T_LIGNES=`tput lines`         #  Définit les dimensions actuels du terminal
T_COLONNES=`tput cols`        #+ en lignes et colonnes.
         
if [ $1 -lt 1 ] || [ $1 -gt $T_LIGNES ]; then    #  Commence la vérification des
   exit $E_MAUVAISARGS                           #+ arguments.
fi
if [ $2 -lt 1 ] || [ $2 -gt $T_COLONNES ]; then
   exit $E_MAUVAISARGS
fi
if [ `expr $1 + $HAUTEUR_BOITE + 1` -gt $T_LIGNES ]; then
   exit $E_MAUVAISARGS
fi
if [ `expr $2 + $LARGEUR_BOITE + 1` -gt $T_COLONNES ]; then
   exit $E_MAUVAISARGS
fi
if [ $3 -lt 1 ] || [ $4 -lt 1 ]; then
   exit $E_MAUVAISARGS
fi                                 # Fin de la vérification des arguments.

plot_char(){                       # Fonction à l'intérieur d'une fonction.
   echo -e "\E[${1};${2}H"$3
}

echo -ne "\E[3${5}m"               #  Initialise la couleur du cadre de la boîte
                                   #+ si elle est définie.

# start drawing the box

compteur=1                                       #  Dessine les lignes verticales
for (( r=$1; compteur<=$HAUTEUR_BOITE; r++)); do #+ en utilisant la fonction
  plot_char $r $2 $VERT                          #+ plot_char.
  let compteur=compteur+1
done 

compteur=1
c=`expr $2 + $LARGEUR_BOITE`
for (( r=$1; compteur<=$HAUTEUR_BOITE; r++)); do
  plot_char $r $c $VERT
  let compteur=compteur+1
done 

compteur=1                                       #  Dessine les lignes horizontales
for (( c=$2; compteur<=$LARGEUR_BOITE; c++)); do #+  en utilisant la fonction
  plot_char $1 $c $HORZ                          #+ plot_char.
  let compteur=compteur+1
done 

compteur=1
r=`expr $1 + $HAUTEUR_BOITE`
for (( c=$2; compteur<=$LARGEUR_BOITE; c++)); do
  plot_char $r $c $HORZ
  let compteur=compteur+1
done 

plot_char $1 $2 $CARACTERE_DU_COIN           # Dessine les angles de la boîte.
plot_char $1 `expr $2 + $LARGEUR_BOITE` $CARACTERE_DU_COIN
plot_char `expr $1 + $HAUTEUR_BOITE` $2 $CARACTERE_DU_COIN
plot_char `expr $1 + $HAUTEUR_BOITE` `expr $2 + $LARGEUR_BOITE` $CARACTERE_DU_COIN

echo -ne "\E[0m"               #  Restaure les anciennes couleurs.

P_ROWS=`expr $T_LIGNES - 1`    #  Place l'invite au bas du terminal.

echo -e "\E[${P_ROWS};1H"
}      


# Maintenant, essayons de dessiner une boîte.
clear                                # Efface le terminal.
R=2      # Ligne
C=3      # Colonne
H=10     # Hauteur
W=45     # Largeur
col=1    # Couleur (rouge)
dessine_une_boite $R $C $H $W $col   # Dessine la boîte.

exit 0

# Exercice :
# ---------
# Ajoutez l'option d'impression de texte dans la boîte dessinée.

La séquence d'échappement ANSI la plus simple et peut-être la plus utile est du texte gras, \033[1m ... \033[0m. \033 représente un escape, « [1 » active l'attribut gras, alors que « [0 » la désactive. « m » termine chaque terme de la séquence d'échappement.

bash$ echo -e "\033[1mCeci est un texte en gras.\033[0m"
              

Une séquence d'échappement similaire active l'attribut de soulignement (sur un rxvt et un aterm).

bash$ echo -e "\033[4mCe texte est souligné.\033[0m"
              
[Note]

Note

Avec un echo, l'option -e active les séquences d'échappement.

D'autres séquences d'échappement modifie le texte et/ou la couleur du fond.

bash$ echo -e '\E[34;47mCeci est affiché en bleu.'; tput sgr0


bash$ echo -e '\E[33;44m'"texte jaune sur fond bleu"; tput sgr0

bash$ echo -e '\E[1;33;44m'"texte jaune en gras sur
fond bleu"; tput sgr0

              
[Note]

Note

Il est généralement conseillé d'initialiser l'attribut gras pour le texte coloré avec des teintes claires.

tput sgr0 restaure les paramétrages du terminal en normal. L'omettre laisse toute sortie ultérieure à partir de ce terminal en bleu.

[Note]

Note

Comme tput sgr0 échoue lors de la restauration des paramètres du terminal sous certaines circonstances, echo -ne \E[0m pourrait être un meilleur choix.

Les nombres dans la table suivante fonctionnent pour un terminal rxvt. Les résultats peuvent varier pour d'autres émulateurs de terminaux.

Tableau 33.2. Nombres représentant les couleurs des séquences d'échappement

Couleur Avant-plan Arrière-plan
noir 30 40
rouge 31 41
vert 32 42
jaune 33 43
bleu 34 44
magenta 35 45
cyan 36 46
blanc 37 47

Exemple 33.13. Afficher du texte coloré

#!/bin/bash
# color-echo.sh : Affiche des messages texte en couleur.

# Modifier ce script pour vos besoins propres.
# C'est plus facile que de coder manuellement les couleurs.

noir='\E[30;47m'
rouge='\E[31;47m'
vert='\E[32;47m'
jaune='\E[33;47m'
bleu='\E[34;47m'
magenta='\E[35;47m'
cyan='\E[36;47m'
blanc='\E[37;47m'


alias init="tput sgr0"       #  Initialise les attributs texte à la normale
                             #+ sans effacer l'écran.


cecho ()                     # Echo couleur.
                             # Argument $1 = message
                             # Argument $2 = couleur
{
local msg_par_defaut="Pas de message."
                             # N'a pas réellement besoin d'être une variable
                             # locale.

message=${1:-$msg_par_defaut}# Message par défaut.
couleur=${2:-$noir}          # Noir par défaut si non spécifié.

  echo -e "$color"
  echo "$message"
  init                       # Retour à la normale.

  return
}  


# Maintenant, essayons-le.
# ----------------------------------------------------
cecho "Je me sens bleu..." $bleu
cecho "Le magenta ressemble plus à du violet." $magenta
cecho "Vert avec envie." $vert
cecho "Vous voyez rouge ?" $rouge
cecho "Cyan, mieux connu sous le nom d'aqua." $cyan
cecho "Pas de couleur précisée (noir par défaut)."
       # Argument $color manquant.
cecho "Couleur \"vide\" passée (noir par défaut)." ""
       # Argument $color vide.
cecho
       # Arguments $message et $color manquants.
cecho "" ""
       # Arguments $message et $color vides.
# ----------------------------------------------------

echo

exit 0

# Exercices :
# ----------
# 1) Ajouter l'attribut "gras" à la fonction 'cecho ()'.
# 2) Ajouter des options pour des fonds colorés.

Exemple 33.14. Un jeu de « courses de chevaux »

#!/bin/bash
# horserace.sh : simulation très simple d'une course de chevaux.
# Auteur : Stefano Palmeri
# Utilisé avec sa permission.

##############################################################################
#  But du script :
#  jouer avec les séquences d'échappement et les couleurs du terminal.
#
#  Exercice :
#  Modifiez le script pour qu'il fonctionne de façon moins aléatoire,
#+ construisez un faux magasin de paris...
#  Hum... Hum... cela me rappelle un film...
#
#  Le script donne un handicap (au hasard) à chaque cheval.
#  Les chances sont calculées suivant le handicap du cheval
#+ et sont exprimées dans le style européen (?).
#  Par exemple : odds=3.75 signifie que si vous pariez 1$ et que vous gagnez,
#+ vous recevrez $3.75.
# 
#  Le script a été testé avec un système d'exploitation GNU/Linux,
#+ en utilisant xterm, rxvt et konsole.
#  Sur une machine disposant d'un processeur AMD 900 MHz,
#+ le temps moyen d'une course est de 75 secondes...
#  Sur des ordinateurs plus rapides, le temps serait encore plus faible.
#  Donc, si vous voulez plus de suspens, réinitialisez la variable ARG_USLEEP.
#
#  Script de Stefano Palmeri.
##############################################################################

E_ERREXEC=65

# Vérifie si md5sum et bc sont installés.
if ! which bc &> /dev/null; then
   echo "bc n'est pas installé."
   echo "Impossible de continuer..."
   exit $E_ERREXEC
fi
if ! which md5sum &> /dev/null; then
   echo "md5sum n'est pas installé."
   echo "Impossible de continuer..."
   exit $E_ERREXEC
fi

#  Configurez la variable suivante pour ralentir l'exécution du script.
#  Elle sera passée comme argument de usleep (man usleep)
#+ et est exprimée en microsecondes (500000 = une demi-seconde).
ARG_USLEEP=0  

#  Nettoie le répertoire temporaire, restaure le curseur du terminal et
#+ ses couleurs - si le script a été interrompu par Ctl-C.
trap 'echo -en "\E[?25h"; echo -en "\E[0m"; stty echo;\
tput cup 20 0; rm -fr  $REP_TEMP_COURSE_CHEVAUX'  TERM EXIT
#  Voir le chapitre sur le débogage pour une explication de 'trap.'

#  Configure un nom unique (paranoïaque) pour le répertoire temporaire
#+ dont a besoin le script.
REP_TEMP_COURSE_CHEVAUX=$HOME/.horserace-`date +%s`-`head -c10 /dev/urandom \
| md5sum | head -c30`

# Crée le répertoire temporaire et s'y place.
mkdir $REP_TEMP_COURSE_CHEVAUX
cd $REP_TEMP_COURSE_CHEVAUX


#  Cette fonction déplace le curseur sur la ligne $1, colonne $2 puis affiche $3.
#  Par exemple :  "deplace_et_affiche 5 10 linux" est équivalent à
#+ "tput cup 4 9; echo linux", mais avec une seule commande au lieu de deux.
#  Note : "tput cup" définit 0 0 comme étant l'angle en haut à gauche du terminal,
#+ echo définit 1 1 comme étant l'angle en haut à gauche du terminal.
deplace_et_affiche() {
          echo -ne "\E[${1};${2}H""$3" 
}

# Fonction pour générer un nombre pseudo-aléatoire entre 1 et 9.
hasard_1_9 ()
{
                head -c10 /dev/urandom | md5sum | tr -d [a-z] | tr -d 0 | cut -c1 
}

#  Deux fonctions simulant un "mouvement" lors de l'affichage des chevaux.
dessine_cheval_un() {
               echo -n " "//$DEPLACE_CHEVAL//
}
dessine_cheval_deux(){
              echo -n " "\\\\$DEPLACE_CHEVAL\\\\ 
}   


# Définit les dimensions actuelles du terminal.
N_COLS=`tput cols`
N_LIGNES=`tput lines`

# A besoin d'un terminal avec au moins 20 lignes et 80 colonnes. Vérifiez-le.
if [ $N_COLS -lt 80 ] || [ $N_LIGNES -lt 20 ]; then
   echo "`basename $0` a besoin d'un terminal à 80 colonnes et 20 lignes."
   echo "Votre terminal fait ${N_COLS} colonnes sur ${N_LIGNES} lignes."
   exit $E_ERREXEC
fi


# Commence par le dessin du champ de course.

# A besoin d'une chaîne de 80 caractères. Voir ci-dessous.
ESPACES80=`seq -s "" 100 | head -c80`

clear

# Configure les couleurs en avant et en arrière-plan à blanc.
echo -ne '\E[37;47m'

# Déplace le curseur à l'angle en haut à gauche du terminal.
tput cup 0 0 

# Dessine six lignes blanches.
for n in `seq 5`; do
      echo $ESPACES80        # Utilise les 80 caractères pour coloriser le terminal.
done

# Configure la couleur en avant-plan à noir.
echo -ne '\E[30m'

deplace_et_affiche 3 1 "START  1"            
deplace_et_affiche 3 75 FINISH
deplace_et_affiche 1 5 "|"
deplace_et_affiche 1 80 "|"
deplace_et_affiche 2 5 "|"
deplace_et_affiche 2 80 "|"
deplace_et_affiche 4 5 "|  2"
deplace_et_affiche 4 80 "|"
deplace_et_affiche 5 5 "V  3"
deplace_et_affiche 5 80 "V"

# Configure la couleur en avant-plan à rouge.
echo -ne '\E[31m'

# Un peu d'art ASCII.
deplace_et_affiche 1 8 "..@@@..@@@@@...@@@@@.@...@..@@@@..."
deplace_et_affiche 2 8 ".@...@...@.......@...@...@.@......."
deplace_et_affiche 3 8 ".@@@@@...@.......@...@@@@@.@@@@...."
deplace_et_affiche 4 8 ".@...@...@.......@...@...@.@......."
deplace_et_affiche 5 8 ".@...@...@.......@...@...@..@@@@..."
deplace_et_affiche 1 43 "@@@@...@@@...@@@@..@@@@..@@@@."
deplace_et_affiche 2 43 "@...@.@...@.@.....@.....@....."
deplace_et_affiche 3 43 "@@@@..@@@@@.@.....@@@@...@@@.."
deplace_et_affiche 4 43 "@..@..@...@.@.....@.........@."
deplace_et_affiche 5 43 "@...@.@...@..@@@@..@@@@.@@@@.."


# Configure la couleur en avant-plan et en arrière-plan à vert.
echo -ne '\E[32;42m'

# Dessine onze lignes vertes.
tput cup 5 0
for n in `seq 11`; do
      echo $ESPACES80
done

# Configure la couleur en avant-plan à noir.
echo -ne '\E[30m'
tput cup 5 0

# Dessine les limites.
echo "++++++++++++++++++++++++++++++++++++++\
++++++++++++++++++++++++++++++++++++++++++"

tput cup 15 0
echo "++++++++++++++++++++++++++++++++++++++\
++++++++++++++++++++++++++++++++++++++++++"

# Configure la couleur en avant et en arrière-plan à blanc.
echo -ne '\E[37;47m'

# Dessine trois lignes blanches.
for n in `seq 3`; do
      echo $ESPACES80
done

# Configure la couleur en avant-plan à noir.
echo -ne '\E[30m'

# Crée neuf fichiers pour stocker les handicaps.
for n in `seq 10 7 68`; do
      touch $n
done  

# Configure le premier type de "cheval" que le script dessinera.
TYPE_CHEVAL=2

#  Crée un fichier position et un fichier chance pour chaque "cheval".
#+ Dans ces fichiers, stocke la position actuelle du cheval,
#+ le type et les chances.
for HN in `seq 9`; do
      touch position_${HN}_cheval
      touch chances_${HN}
      echo \-1 > position_${HN}_cheval
      echo $TYPE_CHEVAL >>  position_${HN}_cheval
      # Définit un handicap au hasard pour un cheval.
       HANDICAP=`hasard_1_9`
      # Vérifie si la fonction hasard_1_9 a renvoyé une bonne valeur.
      while ! echo $HANDICAP | grep [1-9] &> /dev/null; do
                HANDICAP=`hasard_1_9`
      done
      # Définit la dernière position du handicap pour le cheval.
      LHP=`expr $HANDICAP \* 7 + 3`
      for FILE in `seq 10 7 $LHP`; do
            echo $HN >> $FILE
      done   

      # Calcule les chances.
      case $HANDICAP in 
              1) CHANCES=`echo $HANDICAP \* 0.25 + 1.25 | bc`
                 echo $CHANCES > chances_${HN}
              ;;
              2 | 3) CHANCES=`echo $HANDICAP \* 0.40 + 1.25 | bc`
                 echo $CHANCES > chances_${HN}
              ;;
              4 | 5 | 6) CHANCES=`echo $HANDICAP \* 0.55 + 1.25 | bc`
                 echo $CHANCES > chances_${HN}
              ;; 
              7 | 8) CHANCES=`echo $HANDICAP \* 0.75 + 1.25 | bc`
                 echo $CHANCES > chances_${HN}
              ;; 
              9) CHANCES=`echo $HANDICAP \* 0.90 + 1.25 | bc`
                 echo $CHANCES > chances_${HN}
      esac


done


# Affiche les chances.
affiche_chances() {
tput cup 6 0
echo -ne '\E[30;42m'
for HN in `seq 9`; do
      echo "#$HN odds->" `cat chances_${HN}`
done
}

# Dessine les chevaux sur la ligne de départ.
dessine_chevaux() {
tput cup 6 0
echo -ne '\E[30;42m'
for HN in `seq 9`; do
      echo /\\$HN/\\"                               "
done
}

affiche_chances

echo -ne '\E[47m'
# Attend l'appui sur la touche Enter pour commencer la course.
# La séquence d'échappement '\E[?25l' désactive le curseur.
tput cup 17 0
echo -e '\E[?25l'Appuyez sur la touche [enter] pour lancer la course...
read -s

#  Désactive l'affichage normal sur le terminal.
#  Ceci évite qu'une touche appuyée "contamine" l'écran pendant la course...
stty -echo

# --------------------------------------------------------
# Début de la course.

dessine_chevaux
echo -ne '\E[37;47m'
deplace_et_affiche 18 1 $ESPACES80
echo -ne '\E[30m'
deplace_et_affiche 18 1 Starting...
sleep 1

# Configure la colonne de la ligne finale.
POS_GAGNANTE=74

# Définit le moment où la course a commencé.
HEURE_DEBUT=`date +%s`

# Variable COL nécessaire pour la construction "while".
COL=0

while [ $COL -lt $POS_GAGNANTE ]; do

          DEPLACE_CHEVAL=0

          # Vérifie si la fonction hasard_1_9 a renvoyé une bonne valeur.
          while ! echo $DEPLACE_CHEVAL | grep [1-9] &> /dev/null; do
                DEPLACE_CHEVAL=`hasard_1_9`
          done

          # Définit l'ancien type et position du "cheval au hasard".
          TYPE_CHEVAL=`cat  position_${DEPLACE_CHEVAL}_cheval | tail -n 1`
          COL=$(expr `cat  position_${DEPLACE_CHEVAL}_cheval | head -n 1`) 

          ADD_POS=1
          # Vérifie si la position actuelle est une position de handicap.
          if seq 10 7 68 | grep -w $COL &> /dev/null; then
                if grep -w $DEPLACE_CHEVAL $COL &> /dev/null; then
                      ADD_POS=0
                      grep -v -w  $DEPLACE_CHEVAL $COL > ${COL}_new
                      rm -f $COL
                      mv -f ${COL}_new $COL
                      else ADD_POS=1
                fi 
          else ADD_POS=1
          fi
          COL=`expr $COL + $ADD_POS`
          echo $COL >  position_${DEPLACE_CHEVAL}_cheval  # Stocke la nouvelle position.

          # Choisit le type de cheval à dessiner.
          case $TYPE_CHEVAL in 
                1) TYPE_CHEVAL=2; DRAW_HORSE=dessine_cheval_deux
                ;;
                2) TYPE_CHEVAL=1; DRAW_HORSE=dessine_cheval_un 
          esac
          echo $TYPE_CHEVAL >>  position_${DEPLACE_CHEVAL}_cheval
          # Stocke le type actuel.

          # Configure l'avant et l'arrière-plan à vert.
          echo -ne '\E[30;42m'

          # Déplace le curseur à la nouvelle position du cheval.
          tput cup `expr $DEPLACE_CHEVAL + 5` \
          `cat  position_${DEPLACE_CHEVAL}_cheval | head -n 1` 

          # Dessine le cheval.
          $DRAW_HORSE
          usleep $ARG_USLEEP

          #  Quand tous les chevaux ont passé la ligne du champ 15,
          #+ affiche de nouveau les chances.
          touch champ15
          if [ $COL = 15 ]; then
            echo $DEPLACE_CHEVAL >> champ15  
          fi
          if [ `wc -l champ15 | cut -f1 -d " "` = 9 ]; then
              affiche_chances
              : > champ15
          fi

          # Définit le cheval en tête.
          MEILLEURE_POS=`cat *position | sort -n | tail -1`          

          # Configure la couleur de l'arrière-plan à blanc.
          echo -ne '\E[47m'
          tput cup 17 0
          echo -n Current leader: `grep -w $MEILLEURE_POS *position | cut -c7`\
          "                              "

done  

# Définit le moment où la course s'est terminée.
HEURE_FIN=`date +%s`

# Configure la couleur de l'arrière blanc à vert et active le clignotement du texte.
echo -ne '\E[30;42m'
echo -en '\E[5m'

# Fait en sorte que le gagnant clignotte.
tput cup `expr $DEPLACE_CHEVAL + 5` \
`cat  position_${DEPLACE_CHEVAL}_cheval | head -n 1`
$DESSINE_CHEVAL

# Désactive le clignotement du texte.
echo -en '\E[25m'

# Configure la couleur d'avant et d'arrière-plan à blanc.
echo -ne '\E[37;47m'
deplace_et_affiche 18 1 $ESPACES80

# Configure la couleur d'avant-plan à noir.
echo -ne '\E[30m'

# Fait que le gagnant clignotte.
tput cup 17 0
echo -e "\E[5mWINNER: $DEPLACE_CHEVAL\E[25m""  Odds: `cat odds_${DEPLACE_CHEVAL}`"\
"  Race time: `expr $HEURE_FIN - $HEURE_DEBUT` secs"

# Restaure le curseur et les anciennes couleurs.
echo -en "\E[?25h"
echo -en "\E[0m"

# Restaure l'affiche normal.
stty echo

# Supprime le répertoire temporaire de la course.
rm -rf $REP_TEMP_COURSE_CHEVAUX

tput cup 19 0

exit 0

Voir aussi l'Exemple A.23, « Coloriser du texte en utilisant les fonctions de hachage », Exemple A.42, « Un outil de résolution général » et Exemple A.40, « Pétales autour d'une rose ».

[Attention]

Attention

Il existe néanmoins un problème majeur avec tout ceci. Les séquences d'échappement ANSI sont généralement non portables. Ce qui fonctionne bien sur certains émulateurs de terminaux (ou la console) peut fonctionner différemment, ou pas du tout, sur les autres. Un script « coloré » ayant une excellente forme sur la machine de l'auteur du script peut produire une sortie illisible chez quelqu'un d'autre. Ceci compromet grandement l'utilité de la « colorisation » des scripts, et relègue cette technique au statut de gadget, voire de « jeu ».

L'utilitaire color de Moshe Jacobson (http://runslinux.net/projects.html#color) simplifie considérablement l'utilisation des séquences d'échappement ANSI. Il substitue une syntaxe claire et logique aux constructions bizarres dont on a discutées.

Henry/teikedvl a créé un outil (http://scriptechocolor.sourceforge.net/) pour simplifier la création de scripts colorisés.



[102] ANSI est, bien sûr, l'acronyme pour « American National Standards Institute ». Ce corps auguste établit et maintient différents standards techniques et industriels.