L'adaptation à la région géographique est une fonctionnalité non documentée de Bash.
Un script shell adapté affiche son texte dans la langue définie par le paramètre système. Un utilisateur Linux à Berlin, Allemagne, aura une sortie en allemand alors que son cousin à Berlin, Maryland, aura une sortie en anglais avec le même script.
Pour créer un script autochtone, utilisez le modèle suivant pour écrire tous les messages pour l'utilisateur (messages d'erreur, invite, etc.).
#!/bin/bash
# localized.sh
# Script écrit par Stéphane Chazelas,
# modifié par Bruno Haible et corrigé par Alfredo Pironti
. gettext.sh
E_CDERROR=65
error()
{
printf "$@" >&2
exit $E_CDERROR
}
cd $var || error "`eval_gettext \"Ne peut pas entrer dans \$var.\"`"
# Le triple antislash (échappements) en face de $var est nécessaire
#+ "parce que eval_gettext attend une chaîne là où les valeurs des
#+ variables n'ont pas encore été substituées."
# -- par Bruno Haible
read -p "`gettext \"Entrez la valeur : \"`" var
# ...
# ------------------------------------------------------------------
# Alfredo Pironti commente :
# Ce script a été modifié pour ne pas utiliser la syntaxe $"..."
#+ en faveur de la syntaxe "`gettext \"...\"`".
# C'est OK mais, avec le nouveau programme localized.sh, les commandes
#+ "bash -D fichier" et "bash --dump-po-string fichier" ne produiront
#+ aucune sortie
#+ (car ces commandes recherchent seulement les chaînes $"...") !
# L'UNIQUE façon d'extraire les chaînes du nouveau fichier est d'utiliser
# le programme 'xgettext'. Néanmoins, le programme xgettext est boguée.
# Notez qu'xgettext a un autre bogue.
#
# Le fragment de shell :
# gettext -s "I like Bash"
# sera correctement extrait mais...
# xgettext -s "I like Bash"
# ... échoue!
# 'xgettext' extraiera "-s" parce que
#+ la commande extrait seulement le tout premier argument
#+ après le mot 'gettext'.
# Caractère d'échappement :
#
# Pour adapter une phrase comme
# echo -e "Bonjour\tmonde!"
#+ vous devez utiliser
# echo -e "`gettext \"Bonjour\\tmonde\"`"
# Le "caractère d'échappement double" avant le `t' est nécessaire parce que
#+ 'gettext' cherchera une chaîne identique à : 'Bonjour\tmonde'
# Ceci est dû au fait que gettext lira un littéral `\')
#+ et affichera une chaîne comme "Bonjour\tmonde",
#+ donc la commande 'echo' affichera le message correctement.
#
# Vous ne pouvez pas utiliser
# echo "`gettext -e \"Bonjour\tmonde\"`"
#+ à cause du bogue d'xgettext expliqué ci-dessus.
# Localisons le fragment de shell suivant :
# echo "-h display help and exit"
#
# Tout d'abord, vous pourriez faire ceci :
# echo "`gettext \"-h display help and exit\"`"
# De cette façon, 'xgettext' fonctionnera bien
#+ mais le programme 'gettext' lira "-h" comme une option !
#
# Une solution serait
# echo "`gettext -- \"-h display help and exit\"`"
# De cette façon, 'gettext' fonctionnera
#+ mais 'xgettext' extraiera "--" comme indiqué ci-dessus.
#
# Le contournement que vous pourriez utiliser
#+ pour obtenir l'adaptation de la chaîne est
# echo -e "`gettext \"\\0-h display help and exit\"`"
# Nous avons ajouté un \0 (NULL) au début de la phrase.
# De cette façon, 'gettext' fonctionnera bien ainsi que 'xgettext.'
# De plus, le caractère NULL ne modifiera pas le comportement de la commande
#+ 'echo'.
# ------------------------------------------------------------------
bash$ bash -D localized.sh "Can't cd to %s." "Enter the value: "
Ceci liste tout le texte adapté (l'option -D liste les chaînes de caractères mises entre double guillemets préfixées par un $ sans exécuter le script).
bash$ bash --dump-po-strings localized.sh #: a:6 msgid "Can't cd to %s." msgstr "" #: a:7 msgid "Enter the value: " msgstr ""
L'option --dump-po-strings de Bash ressemble à l'option -D mais utilise le format « po » de gettext.
Bruno Haible précise :
À partir de gettext-0.12.2, xgettext -o - localized.sh est recommandé à la place de bash --dump-po-strings localized.sh parce que xgettext . . .
1. comprend les commandes gettext et eval_gettext (alors que bash --dump-po-strings comprend seulement la syntaxe obsolète $"...")
2. peut extraire les commentaires placés par le développeur à l'intention du traducteur.
Ce code shell n'est donc pas spécifique à Bash ; il fonctionne de la même façon avec Bash 1.x et sous les autres implémentations de /bin/sh.
Maintenant, construisez un fichier langage.po pour chaque langage dans lequel le script sera traduit, en spécifiant le msgstr. Alfredo Pironti donne l'exemple suivant :
fr.po:
#: a:6 msgid "Can't cd to $var." msgstr "Impossible de se positionner dans le répertoire $var." #: a:7 msgid "Enter the value: " msgstr "Entrez la valeur : " # Les chaînes sont affichées avec les noms de variable, et non pas avec la #+ syntaxe %s similaire aux programmes C. #+ C'est une fonctionnalité géniale si le développeur utilise des noms de #+ variables qui ont un sens !
Ensuite, lancez msgfmt.
msgfmt -o localized.sh.mo fr.po
Placez le fichier résultant localized.sh.mo dans le répertoire /usr/local/share/locale/fr/LC_MESSAGES et ajoutez les lignes suivantes au début du script :
TEXTDOMAINDIR=/usr/local/share/locale TEXTDOMAIN=localized.sh
Si un utilisateur d'un système français lance le script, il obtiendra des messages en français.
Avec les anciennes versions de Bash ou d'autres shells, gettext avec l'option -s est obligatoire. Dans ce cas, le script devient :
#!/bin/bash
# localized.sh
E_CDERROR=65
error() {
local format=$1
shift
printf "$(gettext -s "$format")" "$@" >&2
exit $E_CDERROR
}
cd $var || error "Can't cd to %s." "$var"
read -p "$(gettext -s "Enter the value: ")" var
# ...
Les variables TEXTDOMAIN et TEXTDOMAINDIR doivent être initialisées et exportées dans l'environnement. Cela doit être fait à l'intérieur du script.
---
Cette annexe a été écrite par Stéphane Chazelas avec quelques améliorations suggérées par Alfredo Pironti et Bruno Haible, le mainteneur de gettext.