在 bash 中使用 gettext

发布于 2024-08-21 05:07:09 字数 628 浏览 8 评论 0 原文

如何在bash脚本中使用gettext?

我只找到了这个页面,但我不明白。

本地化

我的脚本是这样写的:

 #!/bin/bash
 . lang_file.sh
 echo $LANG_HELLO_WORLD

lang_file.sh 看起来像这样:

 #!/bin/bash
 LANG_HELLO_WORLD="Hello World"

我想使用 gettext 将 lang_file.sh 更改为某些内容,如下所示:

 #!/bin/bash
 LANG_HELLO_WORLD=`some gettext command to get string in user language`

我想使用 Launchpad 中的代码,以便其他用户可以翻译它(.po、.pot 文件)

抱歉英语不好,有什么建议吗?

How to use gettext in bash script?

I only found this page, but I don't understand it.

Localization

My script is written like this:

 #!/bin/bash
 . lang_file.sh
 echo $LANG_HELLO_WORLD

And lang_file.sh look like that:

 #!/bin/bash
 LANG_HELLO_WORLD="Hello World"

I want to change lang_file.sh to something using gettext, like this:

 #!/bin/bash
 LANG_HELLO_WORLD=`some gettext command to get string in user language`

I want to use the code in Launchpad, so other users can translate it (.po, .pot files)

Sorry for bad English, any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

最美的太阳 2024-08-28 05:07:09

您需要执行以下步骤:

  1. 确定您的项目名称是什么,gettext 将其称为 textdomain,您将需要它来检索项目的翻译。我们称之为“PRJ”。
  2. 标记要翻译的字符串。以下代码片段给出了示例:

    我们将其命名为PRJ.sh

    <前><代码>#!/bin/sh
    别名 GETTEXT='gettext "PRJ"'

    ## 使用GETTEXT标记要翻译的字符串
    HELLO_WORLD=$(GETTEXT "你好世界")

    回显“$HELLO_WORLD”

  3. 生成 .pot 文件,以便翻译人员可以对其进行处理。

    运行以下命令,它只会查找 GETTEXT,即您真正想要翻译的内容。

    xgettext -o PRJ.pot -L Shell --keyword --keyword=GETTEXT PRJ.sh
    
  4. 可选:生成 .po 文件。

    对于您想要覆盖的每个区域。

    msginit -i PRJ.pot -l fr.UTF-8
    

    请注意,建议使用“UTF-8”,否则msginit可能会错误地为您选择一些过时的编码。

  5. 检索完成的.po文件,并将其转换为.mo文件(机器可以读取的文件)

    msgfmt -v fr.po -o fr.mo
    
  6. 安装.mo 文件。运行:

    sudo install fr.mo /usr/share/locale/fr/LC_MESSAGES/PRJ.mo 
    

    现在您可以尝试结果:

    LANGUAGE=fr ./PRJ.sh
    

    您应该会看到 Hello world 的法语翻译。

You need to preform following steps:

  1. Determine what's your project name, gettext calls it textdomain, you will need it to retrieve the translations for your project. Let's call it "PRJ".
  2. Mark the strings to be translated. Following snippet gives example:

    Let's call it PRJ.sh:

    #!/bin/sh
    alias GETTEXT='gettext "PRJ"'
    
    ## Use GETTEXT to mark the string you want to translate
    HELLO_WORLD=$(GETTEXT "Hello world") 
    
    echo "$HELLO_WORLD"
    
  3. Produce .pot file so translators can work on it.

    Run the following command, it only looks for GETTEXT, the ones you actually want to translate.

    xgettext -o PRJ.pot  -L Shell --keyword --keyword=GETTEXT  PRJ.sh
    
  4. Optional: Generate .po files.

    For each locale you want to cover.

    msginit -i PRJ.pot -l fr.UTF-8
    

    Note that "UTF-8" is sugggested, otherwise msginit may mistakenly choose some obsoleted encoding for you.

  5. Retrieve completed .po files, and convert them to .mo file (the file that machine can read it)

    msgfmt -v  fr.po -o fr.mo
    
  6. Install .mo files. Run:

    sudo install fr.mo /usr/share/locale/fr/LC_MESSAGES/PRJ.mo 
    

    Now you can try the result:

    LANGUAGE=fr  ./PRJ.sh
    

    and you should see French translation for Hello world.

短叹 2024-08-28 05:07:09

bash 中有一个失传已久、从未记录且几乎已弃用的内置解决方案。

LANG=foo_BAR.utf8
TEXTDOMAIN="test" 
TEXTDOMAINDIR="/usr/share/locale"
echo $"fooMsgid"
# bash --dump-po-strings <scriptfile>

There is a long-lost, never-documented and almost-deprecated builtin solution in bash.

LANG=foo_BAR.utf8
TEXTDOMAIN="test" 
TEXTDOMAINDIR="/usr/share/locale"
echo $"fooMsgid"
# bash --dump-po-strings <scriptfile>
原谅过去的我 2024-08-28 05:07:09

gettext翻译使用可编辑格式*.po来存储翻译,并使用编译格式*.mo来加载。

有关文件格式的信息,请参考此处:https://www.gnu.org/software/gettext/manual/html_node/index.html

这里我重点介绍如何尝试gettext 命令来获取简短的翻译。

在您准备好具有内部层次结构(如 /LC_MESSAGES/)的文件夹 /path/to/your/locale 后, .mo(其中 是韩语的 ko_KR),请在 lang_file.sh 中使用以下代码:

#!/bin/bash
export LC_ALL=ko_KR.UTF-8   # if LC_ALL not work, you could try also "LANG" and "LANGUAGE"
export TEXTDOMAINDIR=/path/to/your/locale
# export TEXTDOMAIN="<textdomain>"   # <- optional, set this to save the "<textdomain>" argument for `gettext` below
LANG_HELLO_WORLD="$( gettext "<textdomain>" "Your message to translate" )"

The gettext translation make use of an editable format *.po to store translation, and a compiled format *.mo for loading.

For info of the files format, reference here: section "3 The Format of PO Files" and "10 Producing Binary MO Files" of https://www.gnu.org/software/gettext/manual/html_node/index.html

Here I focus on how to try the gettext command to get a translation in short.

After you prepared a folder /path/to/your/locale with inside-hierarchy like <lang>/LC_MESSAGES/<textdomain>.mo (where <lang> is e.g. ko_KR for Korean), use the following code in your lang_file.sh:

#!/bin/bash
export LC_ALL=ko_KR.UTF-8   # if LC_ALL not work, you could try also "LANG" and "LANGUAGE"
export TEXTDOMAINDIR=/path/to/your/locale
# export TEXTDOMAIN="<textdomain>"   # <- optional, set this to save the "<textdomain>" argument for `gettext` below
LANG_HELLO_WORLD="$( gettext "<textdomain>" "Your message to translate" )"
当爱已成负担 2024-08-28 05:07:09

我认为您想做的是用适当的语言询问用户?您可能希望用户首先选择语言。您所要求的另一部分只是将 $(get_some_str_func) 之类的命令嵌入到变量中。

我没有编写这段代码,但它可能符合您想要做的事情?我不确定,我不完全明白你在问什么。

    function _configure_locale() { # [profile]
        local profile=${1:-EN}
        case ${profile} in
          DE|DE_DE|de_DE)
              LC_ALL="de_DE.UTF-8"
              LANG="de_DE.UTF-8"
              LANGUAGE="de_DE:de:en_US:en"
              ;;
          EN|EN_US|en|en_US)
              LC_ALL="en_US.UTF-8"
              LANG="en_US.UTF-8"
              LANGUAGE="en_US:en"
              ;;
          *)
              echo "ALERT" "${FUNCNAME}: unknown profile '${profile}'"
              ;;
          esac
          LC_PAPER="de_DE.UTF-8"; # independent from locale
          LESSCHARSET="utf-8";    # independent from locale
          MM_CHARSET="utf-8"      # independent from locale
          echo "locale settings" "${LANG}";
          export LC_ALL LANG LANGUAGE LC_PAPER LESSCHARSET MM_CHARSET
    }

What you are looking to do is I think ask the user in the appropriate language? You would probably want the user to pick the language first. The other part of what you are asking is simply just embedding commands like $(get_some_str_func) inside of your variable.

I did not write this code but it might be along the lines of what you are trying to do? I'm not sure, i don't understand fully what you are asking.

    function _configure_locale() { # [profile]
        local profile=${1:-EN}
        case ${profile} in
          DE|DE_DE|de_DE)
              LC_ALL="de_DE.UTF-8"
              LANG="de_DE.UTF-8"
              LANGUAGE="de_DE:de:en_US:en"
              ;;
          EN|EN_US|en|en_US)
              LC_ALL="en_US.UTF-8"
              LANG="en_US.UTF-8"
              LANGUAGE="en_US:en"
              ;;
          *)
              echo "ALERT" "${FUNCNAME}: unknown profile '${profile}'"
              ;;
          esac
          LC_PAPER="de_DE.UTF-8"; # independent from locale
          LESSCHARSET="utf-8";    # independent from locale
          MM_CHARSET="utf-8"      # independent from locale
          echo "locale settings" "${LANG}";
          export LC_ALL LANG LANGUAGE LC_PAPER LESSCHARSET MM_CHARSET
    }
叹沉浮 2024-08-28 05:07:09

这是我尝试为 创建的演示示例代码Bash 参考手册中的国际化脚本 部分。

  1. 创建脚本文件script.sh
#!/bin/bash
# script.sh

TEXTDOMAIN=script
TEXTDOMAINDIR="$PWD"

LANG=$1
# or use following
LC_MESSAGES=$1

echo $"hi"

使其可执行chmod +x script.sh

  1. 创建模板(.pot) 和 PO(.po) 文件:
bash --dump-po-strings script.sh > script.pot
# spanish
cp script.pot es.po
# french
cp script.pot fr.po
  1. 编辑 es.pofr.po > 文件并添加翻译。
    例如 es.po:
#: script.sh:8
msgid "hi"
msgstr "hola"
  1. 编译 PO 文件以创建 .mo 文件
msgfmt -o es.mo es.po
msgfmt -o fr.mo fr.po

# copy to following folder structure in pwd
cp es.mo es/LC_MESSAGES/script.mo
cp fr.mo fr/LC_MESSAGES/script.mo
  1. 运行脚本以使用语言环境:
# find valid locale names
locale -a | egrep 'es|fr'

# use the valid locales to execute script
./script.sh spanish
hola
./script.sh french
salut
./script.sh es_ES
hola
./script.sh fr_FR
salut

注意:该示例使用本地目录中的翻译文件。并且不需要安装到其他常见地方。

Here is my attempt to create a demo example code for Creating Internationalized Scripts section from Bash Reference Manual.

  1. Create a script file script.sh:
#!/bin/bash
# script.sh

TEXTDOMAIN=script
TEXTDOMAINDIR="$PWD"

LANG=$1
# or use following
LC_MESSAGES=$1

echo 
quot;hi"

Make it executable chmod +x script.sh.

  1. Create template(.pot) and PO(.po) files:
bash --dump-po-strings script.sh > script.pot
# spanish
cp script.pot es.po
# french
cp script.pot fr.po
  1. Edit the es.po and fr.po files and add translations.
    For example es.po:
#: script.sh:8
msgid "hi"
msgstr "hola"
  1. Compile PO files to create .mo files
msgfmt -o es.mo es.po
msgfmt -o fr.mo fr.po

# copy to following folder structure in pwd
cp es.mo es/LC_MESSAGES/script.mo
cp fr.mo fr/LC_MESSAGES/script.mo
  1. Run the script to use the locales:
# find valid locale names
locale -a | egrep 'es|fr'

# use the valid locales to execute script
./script.sh spanish
hola
./script.sh french
salut
./script.sh es_ES
hola
./script.sh fr_FR
salut

NOTE: The example used the translation files from local directory. And installation to other common place is not required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文