Monday, October 31, 2011

localizing shell scripts without bashisms, gettext or ... anything

I will explain the basic code that is used first, just in case - experts proceed to code block.

1. First we will deal with variable usage.
to print a variable VAR you can use echo

echo $VAR
But lets say we don't know if VAR will be empty, and then we want to use some default

if you have done a lot of scripting, you may already be thinking something like:

[ "$VAR" ] && echo $VAR || echo "default message"
which is just a shorter way of doing:
if test [ "$VAR" ]
echo $VAR
echo default message
both of which are superfluous, but you will see it a lot when instead you can do this:

echo ${VAR:-default message}

2. Next we will try to understand substring manipulation
Assume we have a variable LANG=en_US
and we only need the part before the "_" (the actual language)

In many scripts you will see something like this:
myLANG=`echo $LANG |cut -d "_" -f1 `
cut is not a shell builtin, so it will slow down the script (not drastically but it will) and can usually be avoided if you use this instead
3. sourcing a file - you can include multiple entire text files worth of code as simply as:

#this file contains all of my functions
. /usr/local/share/myprogram/myfunctions
Now we will get to the whole point; localizing our bash/shell script using only variables, substring manipulation and sourcing a file.  In this case we will just use 2 languages and a single variable, but this can be expanded to as many variables and languages as you would like.

cat /usr/share/locale/en/myprog
VAR="Hello World"

cat /usr/share/locale/es/myprog
VAR="Hola Mundo"

cat /usr/sbin/myprog

echo ${VAR:-Hello World}

Note that the "en"  locale is kind of redundant in this case
You can use the en locale as a template and eliminate the default string in your variable by  instead doing this:

[ -f $LANGPATH ] && . $LANGPATH || . /usr/share/locale/en/myprog

or simply declare all the english variables within the script prior to loading locales:

VAR="Hello World"

No comments:

Post a Comment