Localizzare uno script bash: differenze tra le versioni
(Creata pagina con '{{Versioni compatibili}} __TOC__ == Introduzione == Chi utilizza quotidianamente sistemi operativi *nix based (sia per lavoro che per diletto) lo sa: prima o poi avere a che far...') |
S3v (discussione | contributi) mNessun oggetto della modifica |
||
Riga 7: | Riga 7: | ||
In seguito ci si accorge anche che "concatenare" più comandi/istruzioni insieme può essere davvero utile visto che si riesce ad automatizzare rapidamente operazioni molto lunghe e noiose.<br /> | In seguito ci si accorge anche che "concatenare" più comandi/istruzioni insieme può essere davvero utile visto che si riesce ad automatizzare rapidamente operazioni molto lunghe e noiose.<br /> | ||
Guide in rete che trattano le tecniche di scripting se ne trovano tantissime ed alcune molto ben fatte.<br /> | Guide in rete che trattano le tecniche di scripting se ne trovano tantissime ed alcune molto ben fatte.<br /> | ||
Uno degli aspetti un | Uno degli aspetti un po' meno "esplorati" è la ''localizzazione'' ovvero la tecnica con la quale rendere i propri script "comprensibili" anche a chi non parla la nostra lingua. | ||
Riga 30: | Riga 30: | ||
</pre> | </pre> | ||
Come si può vedere la prima istruzione (riguardante un comando inesistente...) | Come si può vedere la prima istruzione (riguardante un comando inesistente...) restituisce una risposta nella lingua impostata di default. Giocando un po' con la variabile ''$LANGUAGE'' le risposte restituite vengono tradotte "in automatico". | ||
== Tecniche di localizzazione == | == Tecniche di localizzazione == | ||
Una volta presa un | Una volta presa un po' di confidenza con le impostazioni di sistema relative alla lingua, è possibile cominciare subito a darsi da fare per rendere uno script "internazionale"!<br /> | ||
<br /> | <br /> | ||
Lo script che ci si propone di tradurre è abbastanza complesso... | Lo script che ci si propone di tradurre è abbastanza complesso... | ||
Riga 186: | Riga 186: | ||
$ msgfmt -o /usr/share/locale/es/LC_MESSAGES/scriptdifficile.mo es/scriptdifficile.po | $ msgfmt -o /usr/share/locale/es/LC_MESSAGES/scriptdifficile.mo es/scriptdifficile.po | ||
</pre> | </pre> | ||
Si "informerà" a questo punto il nostro script del path dove andare a "cercare" (se esistenti) eventuali sue localizzazioni.<br /> | Si "informerà" a questo punto il nostro script del [[path]] dove andare a "cercare" (se esistenti) eventuali sue localizzazioni.<br /> | ||
Per far questo basterà trasformare la prima riga dello script da così: | Per far questo basterà trasformare la prima riga dello script da così: | ||
<pre> | <pre> | ||
Riga 248: | Riga 248: | ||
$ awk '/^msgid/&&!seen[$0]++;!/^msgid/' en/scriptdifficile.pot > en/scriptdifficile-new.pot | $ awk '/^msgid/&&!seen[$0]++;!/^msgid/' en/scriptdifficile.pot > en/scriptdifficile-new.pot | ||
</pre> | </pre> | ||
== Conclusioni == | == Conclusioni == | ||
Riga 257: | Riga 256: | ||
<br /> | <br /> | ||
Happy translating! | Happy translating! | ||
{{Autori|Autore=[[Utente:Pmate|pmate]] 11:36, 17 ott 2011 (CEST)}} | |||
[[Categoria:Bash Scripting]] | [[Categoria:Bash Scripting]] |
Versione delle 20:13, 17 apr 2012
Versioni Compatibili Tutte le versioni supportate di Debian |
Introduzione
Chi utilizza quotidianamente sistemi operativi *nix based (sia per lavoro che per diletto) lo sa: prima o poi avere a che fare con il linguaggio di scripting bash è una tappa obbligata.
Ci si rende presto conto che è molto più semplice e rapido compiere determinate operazioni direttamente da dentro un terminale che ricorrere a mouse, click, finestre e finestrelle varie.
In seguito ci si accorge anche che "concatenare" più comandi/istruzioni insieme può essere davvero utile visto che si riesce ad automatizzare rapidamente operazioni molto lunghe e noiose.
Guide in rete che trattano le tecniche di scripting se ne trovano tantissime ed alcune molto ben fatte.
Uno degli aspetti un po' meno "esplorati" è la localizzazione ovvero la tecnica con la quale rendere i propri script "comprensibili" anche a chi non parla la nostra lingua.
Operazioni preliminari
Prima di esplorare i vari metodi di approccio al problema è necessario capire "che lingua parla" il nostro sistema:
$ echo $LANG it_IT.UTF-8
Nonostante questa impostazione di default il sistema è capace di "riconoscere" anche altre lingue:
$ locate -w locate: non è stato specificato nessun pattern da cercare $ LANGUAGE=es_ES locate -w locate: ningún patrón de busqueda especificado $ LANGUAGE=de_DE locate -w locate: Keine Muster zum Suchen für vorgegebene $ LANGUAGE=en_US locate -w locate: no pattern to search for specified
Come si può vedere la prima istruzione (riguardante un comando inesistente...) restituisce una risposta nella lingua impostata di default. Giocando un po' con la variabile $LANGUAGE le risposte restituite vengono tradotte "in automatico".
Tecniche di localizzazione
Una volta presa un po' di confidenza con le impostazioni di sistema relative alla lingua, è possibile cominciare subito a darsi da fare per rendere uno script "internazionale"!
Lo script che ci si propone di tradurre è abbastanza complesso...
#!/bin/bash # scriptdifficile # Disclaimer: questo script è molto complicato, se sei debole di cuore non leggere! echo "Ciao!" echo "Ti dovevo dire qualcosa ma non ricordo cosa..." echo "Ci vediamo, a presto!"
Se lo si rende eseguibile e lo si lancia (ovviamente a proprio ed esclusivo rischio e pericolo) il risultato è:
$ chmod +x scriptdifficile $ ./scriptdifficile Ciao! Ti dovevo dire qualcosa ma non ricordo cosa... Ci vediamo, a presto!
Vediamo di creare (per lo meno) due localizzazioni di questo capolavoro: una in inglese e l'altra in spagnolo.
Metodo 1: l'arte di arrangiarsi
Per localizzare in maniera molto semplice lo script si può ricorrere al costrutto case (o anche a quello if... then... else, o anche...):
#!/bin/bash # scriptdifficile # Disclaimer: questo script è molto complicato, se sei debole di cuore non leggere! case $LANG in it* ) STRCIAO="Ciao!" STRMSG="Ti dovevo dire qualcosa ma non ricordo cosa..." STRBYE="Ci vediamo, a presto!" ;; en* ) STRCIAO="Hello!" STRMSG="I had something to say to you but I don't remember what..." STRBYE="See you, bye!" ;; es* ) STRCIAO="Hola!" STRMSG="Tenia algo que decirte pero non me acuerdo que..." STRBYE="Nos vemos, hasta pronto!" ;; * ) STRCIAO="Hello!" STRMSG="I had something to say to you but I don't remember it..." STRBYE="See you, bye!" ;; esac echo $STRCIAO echo $STRMSG echo $STRBYE
Il che porta a questi risultati:
$ ./scriptdifficile Ciao! Ti dovevo dire qualcosa ma non ricordo cosa... Ci vediamo, a presto! $ LANG=en_US ./scriptdifficile Hello! I had something to say to you but I don't remember what... See you, bye! $ LANG=es_ES ./scriptdifficile Hola! Tenia algo que decirte pero non me acuerdo que... Nos vemos, hasta pronto!
Come è facile vedere lo script "legge" la variabile $LANG e imposta le stringhe di conseguenza a seconda del valore viene passato runtime.
Questo metodo, quindi, funziona ma... ha sicuramente almeno due grossi lati negativi:
- è brutto a vedersi (de gustibus...)
- non è pratico, basti pensare ad uno script con qualche centinaio di stringhe da localizzare...
Metodo 2: Il carattere "$"
Questa tecnica ci consentirà di creare con pochi passaggi dei file "modello" (da poter distribuire per essere tradotti) e di compilarli per poi inserirli in una specifica directory di sistema in modo che sia possibile, in automatico, "godere" della localizzazione del nostro script relativamente a come sono impostati i locales nel sistema!
Per creare un file modello basterà "trasformare" lo script così:
#!/bin/bash # scriptdifficile # Disclaimer: questo script è molto complicato, se sei debole di cuore non leggere! echo $"Ciao!" echo $"Ti dovevo dire qualcosa ma non ricordo cosa..." echo $"Ci vediamo, a presto!"
Quello che è cambiato rispetto alla versione originale è la presenza del carattere $ che precede le stringhe che si vogliono tradurre.
Creiamo il file "modello" e guardiamo il suo contenuto:
$ bash --dump-po-strings scriptdifficile > scriptdifficile.pot $ cat scriptdifficile.pot #: scriptdifficile2:6 msgid "Ciao!" msgstr "" #: scriptdifficile:7 msgid "Ti dovevo dire qualcosa ma non ricordo cosa..." msgstr "" #: scriptdifficile:8 msgid "Ci vediamo, a presto!" msgstr ""
Come è facilmente intuibile il comando bash --dump-po-strings non ha fatto altro che effettuare un "parsing" del file scriptdifficile, individuare le stringhe "marcate" con $ e riportarle nel file modello dando loro l'identificativo msgid. Ad ogni msgid è stata "accoppiata" una stringa vuota identificata dal marcatore msgstr. Sarà proprio in corrispondenza dei vari msgstr che bisognerà inserire le stringhe tradotte.
Creiamo due sottodirectory destinate a contenere i file tradotti rispettivamente in inglese e in spagnolo e copiamoci dentro il file modello:
$ mkdir en es $ cp scripdifficile.pot > en/scripdifficile.po $ cp scripdifficile.pot > es/scripdifficile.po
Fatto questo i due file en/scripdifficile.po e es/scripdifficile.po dovranno essere editati a manina...:
$ cat en/scripdifficile.po #: scriptdifficile2:6 msgid "Ciao!" msgstr "Hello!" #: scriptdifficile:7 msgid "Ti dovevo dire qualcosa ma non ricordo cosa..." msgstr "I had something to say to you but I don't remember what..." #: scriptdifficile:8 msgid "Ci vediamo, a presto!" msgstr "See you, bye!" $ cat en/scripdifficile.po #: scriptdifficile2:6 msgid "Ciao!" msgstr "Hola!" #: scriptdifficile:7 msgid "Ti dovevo dire qualcosa ma non ricordo cosa..." msgstr "Tenia algo que decirte pero non me acuerdo que..." #: scriptdifficile:8 msgid "Ci vediamo, a presto!" msgstr "Nos vemos, hasta pronto!"
...e successivamente compilati direttamente nelle directory relative alla lingua corrispondente:
$ msgfmt -o /usr/share/locale/en/LC_MESSAGES/scriptdifficile.mo en/scriptdifficile.po ... $ msgfmt -o /usr/share/locale/es/LC_MESSAGES/scriptdifficile.mo es/scriptdifficile.po
Si "informerà" a questo punto il nostro script del path dove andare a "cercare" (se esistenti) eventuali sue localizzazioni.
Per far questo basterà trasformare la prima riga dello script da così:
#!/bin/bash
a così:
#!/bin/bash TEXTDOMAINDIR=/usr/local/share/locale TEXTDOMAIN=scriptdifficile
E il gioco è fatto!!
Da questo momento in poi lo script "leggerà " le impostazioni di sistema relative alla lingua; se una traduzione per quella lingua è stata compilata e messa nel path corretto, restituirà le stringhe tradotte, altrimenti quelle originali (in questo caso in italiano)!
Modifiche
Questo metodo ha (tra gli altri) il vantaggio di rendere successive eventuali modifiche allo script originale facili da integrare nel file .po.
Per fare un esempio, se si aggiunge una riga a scriptdifficile:
#!/bin/bash # scriptdifficile # Disclaimer: questo script è molto complicato, se sei debole di cuore non leggere! echo $"Ciao!" echo $"Ti dovevo dire qualcosa ma non ricordo cosa..." echo $"Ci vediamo, a presto!" echo $"Questa riga è stata aggiunta"
per integrare le modifiche basterà creare il nuovo file .pot:
$ bash --dump-po-strings scriptdifficile > scriptdifficile-new.pot
e fare il merge:
$ msgmerge --update en/scriptdifficile.po scriptdifficile-new.pot $ msgmerge --update es/scriptdifficile.po scriptdifficile-new.pot ... $ cat en/scriptdifficile.po #: scriptdifficile2:6 msgid "Ciao!" msgstr "Hello!" #: scriptdifficile:7 msgid "Ti dovevo dire qualcosa ma non ricordo cosa..." msgstr "I had something to say to you but I don't remember what..." #: scriptdifficile:8 msgid "Ci vediamo, a presto!" msgstr "See you, bye!" #: scriptdifficile:9 msgid "Questa riga è stata aggiunta" msgstr ""
L'istruzione msgmerge evita di dover intervenire sui file .po "manualmente" per aggiungere/rimuovere/modificare le stringhe di testo.
Tip
Può capitare che all'interno di uno script ci siano delle stringhe identiche ripetute più volte.
In questo caso è possibile "eliminarle" dal file .pot avvalendosi di strumenti come awk, sed, etc.
Ad esempio:
$ awk '/^msgid/&&!seen[$0]++;!/^msgid/' en/scriptdifficile.pot > en/scriptdifficile-new.pot
Conclusioni
Il metodo trattato in questa guida , sebbene semplice ed efficace, viene oggi considerato deprecato.
L'alternativa è quella di evitare il marcatore $ in favore di gettext.
Seguendo questo approccio l'istruzione bash --dump-po-strings deve essere rimpiazzata dall'istruzione xgettext, altrimenti nel creare il file .po si cercherebbe comunque la stringa $...
Purtroppo xgettext, allo stato attuale, sembra soffrire di alcuni bug che ne complicano pesantemente l'utilizzo.
Happy translating!
Guida scritta da: pmate 11:36, 17 ott 2011 (CEST) | Debianized 20% |
Estesa da: | |
Verificata da: | |
Verificare ed estendere la guida | Cos'è una guida Debianized |