[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [volume] [parte]


Capitolo 142.   Shell POSIX: traduzione dei messaggi

È possibile fare in modo che i messaggi generati all'interno di uno script vengano tradotti automaticamente, attraverso Gettext, descritto nel capitolo 585.(1) Per ottenere questo, si incorpora in uno script il codice contenuto nel file gettext.sh, che potrebbe risultare installato nella directory /usr/bin/, come parte del pacchetto che compone proprio Gettext; quindi, nello script si fa uso delle funzioni gettext e eval_gettext, per ottenere la traduzione dei messaggi.

142.1   Esempio iniziale

Per cominciare a comprendere il meccanismo, conviene partire da un esempio molto semplice, vedendo dall'inizio alla fine il procedimento. Si suppone che il file seguente sia denominato bye-bye.sh:

      1 #!/bin/sh
      2 TEXTDOMAINDIR=/tmp
      3 TEXTDOMAIN=bye-bye
      4 export TEXTDOMAINDIR
      5 export TEXTDOMAIN
      6 
      7 . /usr/bin/gettext.sh
      8 
      9 tizio="daniele"
     10 
     11 eval_gettext "bye bye \$tizio"
     12 echo ""
     13 gettext      "bye bye \$tizio"
     14 echo ""

Si può osservare che nella settima riga viene inserito il codice contenuto nel file /usr/bin/gettext.sh, quindi si rendono disponibili le funzioni eval_gettext e gettext. Nelle righe numero 11 e numero 13, si vede l'uso delle due funzioni, però con gli stessi argomenti; lì si deve osservare che in entrambi i casi, il dollaro che precede il nome della variabile tizio è stato protetto in modo da non essere espanso dalla shell.

Una volta realizzato il file, si utilizza xgettext per generare il file messages.po, da tradurre. In questo caso, il nome bye-bye.sh è stato scelto appositamente con l'estensione .sh, per facilitare a xgettext il riconoscimento del contesto:

xgettext bye-bye.sh[Invio]

Se non si commettono errori, si ottiene così il file messages.po, con il contenuto seguente:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-04-04 19:24+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: bye-bye.sh:10 bye-bye.sh:12
#, sh-format
msgid "bye bye $tizio"
msgstr ""

Il file va modificato, soprattutto per ciò che riguarda la traduzione. In tal caso, conviene creare il file bye-bye.po:

# bye-bye.sh PO file.
# Copyright (C) 2006 Pinco Pallino
# Pinco Pallino <ppinco@dinkel.brot.dg>, 2006.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: Pinco Pallino <ppinco@dinkel.brot.dg>\n"
"POT-Creation-Date: 2006-04-04 18:59+0200\n"
"PO-Revision-Date: 2006-04-04 18:59+0200\n"
"Last-Translator: Pinco Pallino <ppinco@dinkel.brot.dg>\n"
"Language-Team: Italian <it@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: bye-bye.sh:10 bye-bye.sh:12
#, sh-format
msgid "bye bye $tizio"
msgstr "ciao ciao $tizio"

Si passa quindi alla compilazione del file, con la quale si vuole ottenere il file bye-bye.mo:

msgfmt -vvvv -o bye-bye.mo bye-bye.po[Invio]

Il file bye-bye.mo, tenuto conto che è stato realizzato per la configurazione locale italiana, va collocato all'interno del percorso it/LC_MESSAGES/, che a sua volta deve partire da quanto contenuto nella directory indicata nella variabile TEXTDOMAINDIR, oppure nella collocazione predefinita che potrebbe essere /usr/share/locale/. In questo caso, nello stesso script appare la dichiarazione e l'esportazione della variabile di ambiente TEXTDOMAINDIR (pertanto l'eventuale collocazione predefinita non viene considerata), con un valore tale per cui il file bye-bye.mo deve trovarsi nella directory /tmp/it/LC_MESSAGES/. Inoltre, la variabile TEXTDOMAINDIR stabilisce che sia proprio il file bye-bye.mo quello che deve essere cercato.

Una volta collocato correttamente il file bye-bye.mo, se la configurazione locale è quella della lingua italiana, lo script funziona mostrando i messaggi tradotti:

LANG=it_IT.UTF-8[Invio]

export LANG[Invio]

./bye-bye.sh[Invio]

ciao ciao daniele
ciao ciao $tizio

Il risultato che si ottiene mostra il comportamento delle due funzioni: eval_gettext e gettext. Entrambe le funzioni restituiscono una stringa tradotta, senza aggiungere un codice di interruzione di riga, che infatti nello script viene ottenuto con due comandi echo vuoti. Nel caso della funzione eval_gettext, se la stringa originaria viene scandita alla ricerca di variabili da espandere, mentre la funzione gettext si limita a lasciare inalterata la stringa tradotta.

Si deve osservare che la chiamata delle funzioni *gettext è stata fatta volutamente proteggendo il dollaro davanti al nome della variabile tizio, per evitare che la stringa passata alle funzioni stesse venga espansa preliminarmente dalla shell. Infatti, se ciò accadesse, sarebbe inutile tentare di tradurre i messaggi. Naturalmente, l'uso di una variabile con la funzione gettext diventa del tutto inutile, ma qui serve a dimostrare la differenza di comportamento tra le due funzioni.

142.2   utilizzo più sofisticato

Non è semplice usare le funzioni *gettext così come sono, all'interno di uno script di shell, rispetto a come si può fare invece con un linguaggio di programmazione normale. Qui si propone l'uso di una funzione che serve a estendere le capacità di printf, con la dimostrazione dei raggiri necessari a ottenere il funzionamento del sistema di Gettext. Si suppone che il file seguente sia denominato bye-bye-2.sh:

      1 #!/bin/sh
      2 TEXTDOMAINDIR=/tmp
      3 TEXTDOMAIN=bye-bye-2
      4 export TEXTDOMAINDIR
      5 export TEXTDOMAIN
      6 
      7 . /usr/bin/gettext.sh
      8 
      9 printf_gettext () {
     10     local string="$1"
     11     shift
     12     string=`gettext "$string"`
     13     printf "$string" "$@"
     14 }
     15 
     16 tizio="daniele"
     17 
     18 printf_gettext "bye bye %s\n" $tizio

Per ottenere il file messages.po, occorre imbrogliare xgettext, fingendo che la funzione printf_gettext sia invece soltanto gettext:

cat bye-bye-2.sh | sed "s/printf_gettext/gettext/" | xgettext -L Shell -[Invio]

Se non si commettono errori, si ottiene così il file messages.po, con il contenuto seguente:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-04-05 10:10+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: standard input:19
msgid "bye bye %s\\n"
msgstr "ciao ciao %s\\n"

Come già nella sezione precedente, il file va modificato, soprattutto per ciò che riguarda la traduzione. In tal caso, conviene creare il file bye-bye-2.po:

# bye-bye-2.sh PO file.
# Copyright (C) 2006 Pinco Pallino
# Pinco Pallino <ppinco@dinkel.brot.dg>, 2006.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: Pinco Pallino <ppinco@dinkel.brot.dg>\n"
"POT-Creation-Date: 2006-04-04 18:59+0200\n"
"PO-Revision-Date: 2006-04-04 18:59+0200\n"
"Last-Translator: Pinco Pallino <ppinco@dinkel.brot.dg>\n"
"Language-Team: Italian <it@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: standard input:19
msgid "bye bye %s\\n"
msgstr ""

Si passa quindi alla compilazione del file, con la quale si vuole ottenere il file bye-bye-2.mo:

msgfmt -vvvv -o bye-bye-2.mo bye-bye-2.po[Invio]

Anche in questo caso, data la configurazione delle variabili TEXTDOMAINDIR e TEXTDOMAIN, il file va collocato nella directory /tmp/it/LC_MESSAGES/.

LANG=it_IT.UTF-8[Invio]

export LANG[Invio]

./bye-bye-2.sh[Invio]

ciao ciao daniele

142.3   Riferimenti

Appunti di informatica libera 2007.02 --- Copyright © 2000-2007 Daniele Giacomini -- <daniele (ad) swlibero·org>


1) Gettext   GNU GPL


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome shell_posix_traduzione_dei_messaggi.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico]

Valid ISO-HTML!

CSS validator!