How-To internationalize shell scripts with gettext in 3 easy steps! 1- MODIFICATION OF THE ORIGINAL SCRIPT: (We shall take excerpts from the script keyboardconfig as an example.) 1-a- Add the following lines after the usual introductory comments but before your actual code starts: # Gettext internationalization export TEXTDOMAIN="name_of_the_program" export TEXTDOMAINDIR="destination_path_to_the_compiled_translations" . gettext.sh Example... -> Before modification: # Version 4.3 - 28/07/2009 # * replaced xorg.conf by fdi policy rule # Take a look at "Xdialog" and use it instead of "dialog" in case X is running if [[ "$DISPLAY" && "$(which Xdialog 2>&1 | grep -v "which: no")" ]]; then -> After modification: # Version 4.3 - 28/07/2009 # * replaced xorg.conf by fdi policy rule # Gettext internationalization export TEXTDOMAIN="keyboardconfig" export TEXTDOMAINDIR="/usr/share/locale" . gettext.sh # Take a look at "Xdialog" and use it instead of "dialog" in case X is running if [[ "$DISPLAY" && "$(which Xdialog 2>&1 | grep -v "which: no")" ]]; then 1-b- Put the following tags around the strings that need to be translated: `eval_gettext 'string_to_be_translated'` Exemple... -> Before modification: if [ "$xflag" = "yes" ] ; then answer="$(eval $dialog \ --stdout \ --title \"Keyboard configuration\" \ --default-item \"$currentpathkeymap\" \ --cancel-label \"Exit\" \ --icon \"keyboardconfig\" \ --check \"numlock\" \"on\" \ --menu \ \"\\n Please select your prefered keyboard map:\" 20 75 11 "$list" )" else -> After Modification: if [ "$xflag" = "yes" ] ; then answer="$(eval $dialog \ --stdout \ --title \"`eval_gettext 'Keyboard configuration'`\" \ --default-item \"$currentpathkeymap\" \ --cancel-label \"`eval_gettext 'Exit'`\" \ --icon \"keyboardconfig\" \ --check \"numlock\" \"on\" \ --menu \ \"\\n `eval_gettext 'Please select your prefered keyboard map:'`\" 20 75 11 "$list" )" else 2- TRANSLATION PROCESS: 2-a- We first need to extract the strings to be translated from the shell script to a model file that will be distributed to the translators. To do this, run the following command from the working directory where the shell script is located: xgettext --from-code=utf-8 -L shell -o name_of_shell_script.pot name_of_shell_script Example: xgettext --from-code=utf-8 -L shell -o keyboardconfig.pot keyboardconfig 2-b- Each translator will use the model file to generate his own translation work file by running the following command from the directory where the .pot file (our translation model) is located. It is assumed that the environment locale of his operating system is the same as the locale he wants to translate into (or else he should consult the man page of msginit): msginit -i name_of_shell_script.pot -o name_of_shell_script-name_of_locale.po Example: msginit -i keyboardconfig.pot -o keyboardconfig-fr.po 2-c- Looking into the file is self explanatory, using a text editor of his choice each translator translate the strings in his language po file. Example... Before: #: keyboardconfig:93 keyboardconfig:103 #, sh-format msgid "Keyboard configuration" msgstr "" After: #: keyboardconfig:93 keyboardconfig:103 #, sh-format msgid "Keyboard configuration" msgstr "Configuration du clavier" 3- EXTENDING THE TRANSLATIONS TO THE SHELL SCRIPT: 3-a- When the maintainer of the shell script receives back a completed po file from a translator, he first compiles it by running the following command (from the working directory where the translated po file is located): msgfmt name_of_shell_script-name_of_locale.po -o name_of_shell_script.mo Example: msgfmt keyboardconfig-fr.po -o keyboardconfig.mo 3-b- Then he places the mo file he generated into its appropriate locale directory: /usr/share/locale/name_of_locale/LC_MESSAGES/ Example: /usr/share/locale/fr/LC_MESSAGES/ That's all! NOTES: Maintenance of the shell script & future translations: If later on, the shell script is modified, its maintainer will issue a new pot (model) file as in point 2a which he can send back to the translators. Each translator will then have to run the following command in order to generate a new po file for their language that will include their previous translation work as well as the new strings net yet translated. Both the new pot file & the last translated po file should be located in the directory where this command is issued. msgmerge -U name_of_shell_script-name_of_locale.po name_of_shell_script.pot Exemple: msgmerge -U keyboardconfig-fr.po keyboardconfig.pot And then redo points 2c, 3a & 3b.