Bash multi langues

Même avec des scripts, nous pouvons avoir des utilisateurs allergiques à la langue de shakespeare. Même avec Bash il est très simple de se construire un programme pensé dés le départ pour s’afficher dans notre langue natale (ou en Breton?) si cela devenais nécessaire.

Nous allons dans un premier temps écrire un système de détection de la langue

  • Premièrement nous détectons notre langue par la variable système $LANG
  • Ensuite, nous détectons une option de langue passée éventuellement par la ligne de commande (-l); elle va nous servir à forcer un dictionnaire particulier
lang=${LANG:0:2}
while getopts "l:" option
do
    case $option in
        l)
            #echo "Exécution de la commande de l'option --lang"
            #echo "argument de cette option: $OPTARG"
            lang=$OPTARG
            # supprimer l'option et son argument des paramètres du script pour lire $1 $2 ...
            shift $((OPTIND-1))
            ;;
    esac
done

Pour faire au plus simple, les chaines vont êtres stockées dans des tableaux associatifs, il suffira alors d’avoir un tableau par langue. Ce tableau sera enregistré dans un fichier externe.

Dans notre script nous déclarons notre tableau par défaut (anglais…) de cette façon :

declare -A txt=(
    ['hello']='Hello word'
    ['you']='you'
)

L’utilisation de notre tableau est des plus simple:

echo $txt['hello']

Voila, le travail est fini, il ne nous reste plus qu’a recopier notre tableau(en) dans autant de fichiers externes que nous désirons de langues. Toute la magie va se faire par une petite ligne : 

source "/path/dico.$lang";

notre fichier dico.fr

#!/usr/bin/env bash
## constantes chaines fr {{{
declare -Ar txt=(
    ['hello']='Salut le monde'
    ['you']='vous'
    ['me']='moi'
    ['love']='oui, je vous aime %s pour toujours'
)
# }}}

Le script complet:

#!/usr/bin/env bash
# script pour test script multi langue

## constantes chaine par defaut {{{
declare -A txt=(
    ['hello']='Hello word'
    ['you']='you'
    ['me']='me'
    ['love']='yes, i love you %s for ever'
)
# }}}

## langue en fonction de l'option ou de la langue du shell {{{
lang=${LANG:0:2}
while getopts "l:" option
do
    case $option in
        q)
            echo "Exécution des commandes de l'option q"; exit
            ;;
        l)
            lang=$OPTARG
            # supprimer l'option et son argument des parametres du script pour lire $1 $2 ...
            shift $((OPTIND-1))
            ;;
    esac
done

echo "la langue du script est: $lang"

if [ -f "dico.$lang" ]; then
    # écrasement des chaines dans la bonne langue
    source "dico.$lang";
fi
# }}}

echo -e "---------------\n${txt[hello]}\n---------------\n"

for t in ${!txt[@]} ; do
    echo -e "$t => ${txt[$t]}"
done

echo -e "---------------\n${txt['love']//\%s/toto}\n---------------\n"

Il s’exécute avec éventuellement l’option -l :

./script.sh -l "it"

 

L’utilisation directe de tableau avec sa clé pause un problème : le code n’est pas franchement clair. La solution est simplement d’utiliser comme clé la version anglaise et d’utiliser une fonction à la place de l’appel direct du tableau

 echo "$(_txt 'hello the word')"

 
Passons à la version finale , facilement réutilisable :
 
Nous déclarons nos tableaux dictionnaire de le même façon, ici un fichier « /usr/share/locale/fr/LC_MESSAGES/monprogramme » :

#!/usr/bin/env bash
#dico.fr
declare -Ar _DICO=(
    ['hello the word']='Salut le monde'
    ['i love you %s for ever']='je vous aime %s pour toujours'
)

Nous chargeons automatiquement le dictionnaire en fonction de notre langue :

lg=$(locale 2>/dev/null | awk -F'=' '/^LANG/ {print $2}')    
mydico="/usr/share/locale/${lg:0:2}/LC_MESSAGES/monprogramme"
[ -r "${mydico}" ] && source "${mydico}"

Nous allons utiliser une fonction _txt() qui prend en premier paramètre la clé

_txt() {
   local param="$1"
   shift
   [[ -n "${_DICO[$param]}" ]] && param="${_DICO[$param]}"
   printf "$param" "$@"
}

Utilisation :

echo "$(_txt 'hello the word')"
echo "$(_txt 'yes, i love you %s for ever' $(whoami))"

Pour les tests nous pouvons appeler notre script avec LANG :

LANG=C ./script.sh
LANG=fr ./script.sh
Share Button

Vous devriez aimer...

1 Response

  1. patrick dit :

    Bash prend en charge la localisation; il est possible de jouer aussi avec les fichiers .mo et .po
    http://schplurtz.free.fr/wiki/envrac/bash-international