La localisation est une fonctionnalité non documentée de Bash.
Un script shell adapté (« localisé ») affiche son texte dans la langue définie par le paramètre « locale » du système. Pour un même script, un utilisateur de GNU/Linux à Berlin (Allemagne) verra l'affichage en allemand tandis que son cousin à Berlin (Maryland, USA), verra l'affichage en anglais.
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.