本地化是一个 Bash 未被文档化的特性。
本地化的 shell 脚本以系统区域设置中定义的语言回显其文本输出。德国柏林的 Linux 用户将获得德语的脚本输出,而他在美国马里兰州柏林的表亲将获得来自同一脚本的英语输出。
要创建本地化的脚本,请使用以下模板编写所有给用户的消息(错误消息、提示等)。
#!/bin/bash
# localized.sh
# Script by St�phane Chazelas,
#+ modified by Bruno Haible, bugfixed by Alfredo Pironti.
. gettext.sh
E_CDERROR=65
error()
{
printf "$@" >&2
exit $E_CDERROR
}
cd $var || error "`eval_gettext \"Can\'t cd to \\\$var.\"`"
# The triple backslashes (escapes) in front of $var needed
#+ "because eval_gettext expects a string
#+ where the variable values have not yet been substituted."
# -- per Bruno Haible
read -p "`gettext \"Enter the value: \"`" var
# ...
# ------------------------------------------------------------------
# Alfredo Pironti comments:
# This script has been modified to not use the $"..." syntax in
#+ favor of the "`gettext \"...\"`" syntax.
# This is ok, but with the new localized.sh program, the commands
#+ "bash -D filename" and "bash --dump-po-string filename"
#+ will produce no output
#+ (because those command are only searching for the $"..." strings)!
# The ONLY way to extract strings from the new file is to use the
# 'xgettext' program. However, the xgettext program is buggy.
# Note that 'xgettext' has another bug.
#
# The shell fragment:
# gettext -s "I like Bash"
# will be correctly extracted, but . . .
# xgettext -s "I like Bash"
# . . . fails!
# 'xgettext' will extract "-s" because
#+ the command only extracts the
#+ very first argument after the 'gettext' word.
# Escape characters:
#
# To localize a sentence like
# echo -e "Hello\tworld!"
#+ you must use
# echo -e "`gettext \"Hello\\tworld\"`"
# The "double escape character" before the `t' is needed because
#+ 'gettext' will search for a string like: 'Hello\tworld'
# This is because gettext will read one literal `\')
#+ and will output a string like "Bonjour\tmonde",
#+ so the 'echo' command will display the message correctly.
#
# You may not use
# echo "`gettext -e \"Hello\tworld\"`"
#+ due to the xgettext bug explained above.
# Let's localize the following shell fragment:
# echo "-h display help and exit"
#
# First, one could do this:
# echo "`gettext \"-h display help and exit\"`"
# This way 'xgettext' will work ok,
#+ but the 'gettext' program will read "-h" as an option!
#
# One solution could be
# echo "`gettext -- \"-h display help and exit\"`"
# This way 'gettext' will work,
#+ but 'xgettext' will extract "--", as referred to above.
#
# The workaround you may use to get this string localized is
# echo -e "`gettext \"\\0-h display help and exit\"`"
# We have added a \0 (NULL) at the beginning of the sentence.
# This way 'gettext' works correctly, as does 'xgettext.'
# Moreover, the NULL character won't change the behavior
#+ of the 'echo' command.
# ------------------------------------------------------------------ |
bash$ bash -D localized.sh "Can't cd to %s." "Enter the value: " |
bash$ bash --dump-po-strings localized.sh #: a:6 msgid "Can't cd to %s." msgstr "" #: a:7 msgid "Enter the value: " msgstr "" |
![]() | Bruno Haible 指出 从 gettext-0.12.2 开始,建议使用 xgettext -o - localized.sh 代替 bash --dump-po-strings localized.sh,因为 xgettext . . . 1. 理解 gettext 和 eval_gettext 命令(而 bash --dump-po-strings 仅理解其已弃用的 $"..." 语法) 2. 可以提取程序员放置的、旨在供翻译人员阅读的注释。 此 shell 代码不再特定于 Bash;它在使用 Bash 1.x 和其他 /bin/sh 实现时的工作方式相同。 |
现在,为脚本将被翻译成的每种语言构建一个language.po文件,指定msgstr。 Alfredo Pironti 给出了以下示例
fr.po
#: a:6 msgid "Can't cd to $var." msgstr "Impossible de se positionner dans le repertoire $var." #: a:7 msgid "Enter the value: " msgstr "Entrez la valeur : " # The string are dumped with the variable names, not with the %s syntax, #+ similar to C programs. #+ This is a very cool feature if the programmer uses #+ variable names that make sense! |
然后,运行 msgfmt。
msgfmt -o localized.sh.mo fr.po
将生成的localized.sh.mo文件放在/usr/local/share/locale/fr/LC_MESSAGES目录中,并在脚本的开头插入以下行
TEXTDOMAINDIR=/usr/local/share/locale TEXTDOMAIN=localized.sh |
如果法语系统的用户运行该脚本,她将获得法语消息。
![]() | 对于旧版本的 Bash 或其他 shell,本地化需要使用 gettext,使用-s选项。在这种情况下,脚本变为
|
Bash 的TEXTDOMAIN和TEXTDOMAINDIR变量需要设置并导出到环境。这应该在脚本本身内完成。
---
本附录由 Stéphane Chazelas 编写,并由 Alfredo Pironti 和 GNU gettext 的维护者 Bruno Haible 建议修改。