This appendix comes from the Advanced Bash-Scripting Guide Version 1.8.4, the original copyright page can be found here. I keep this copy around because I find the appendix in the currrent version fails to document $" " which was the most interesting part of this appendix.

Appendix E. Localization

Localization is an undocumented Bash feature.

A localized shell script echoes its text output in the language defined as the system's locale. A Linux user in Berlin, Germany, would get script output in German, whereas his cousin in Berlin, Maryland, would get output from the same script in English.

To create a localized script, use the following template to write all messages to the user (error messages, prompts, etc.).

   1 #!/bin/bash
   2 #
   4 E_CDERROR=65
   6 error()
   7 {
   8   printf "$@" >&2
   9   exit $E_CDERROR
  10 }
  12 cd $var || error $"Can't cd to %s." "$var"
  13 read -p $"Enter the value: " var
  14 # ...

 bash$ bash -D
 "Can't cd to %s."
 "Enter the value: "
This lists all the localized text. (The -D option lists double-quoted strings prefixed by a $, without executing the script.)

 bash$ bash --dump-po-strings
 #: a:6
 msgid "Can't cd to %s."
 msgstr ""
 #: a:7
 msgid "Enter the value: "
 msgstr ""
The --dump-po-strings option to Bash resembles the -D option, but uses gettext "po" format.

Now, build a language.po file for each language that the script will be translated into, specifying the msgstr. As an example:

   1 #: a:6
   2 msgid "Can't cd to %s."
   3 msgstr "Impossible de se positionner dans le répertoire %s."
   4 #: a:7
   5 msgid "Enter the value: "
   6 msgstr "Entrez la valeur : "

Then, run msgfmt.

msgfmt -o fr.po

Place the resulting file in the /usr/local/share/locale/fr/LC_MESSAGES directory, and at the beginning of the script, insert the lines:
   1 TEXTDOMAINDIR=/usr/local/share/locale

If a user on a French system runs the script, she will get French messages.


With older versions of Bash or other shells, localization requires gettext, using the -s option. In this case, the script becomes:

   1 #!/bin/bash
   2 #
   4 E_CDERROR=65
   6 error() {
   7   local format=$1
   8   shift
   9   printf "$(gettext -s "$format")" "$@" >&2
  10   exit $E_CDERROR
  11 }
  12 cd $var || error "Can't cd to %s." "$var"
  13 read -p "$(gettext -s "Enter the value: ")" var
  14 # ...

The TEXTDOMAIN and TEXTDOMAINDIR variables need to be exported to the environment.


This appendix written by Stephane Chazelas.