bash本地化不适用于多行字符串(具有强语法或通过`eval`)

F. *_*uri 12 bash localization

bash有一个很好的功能,关于本地化(语言翻译):

TEXTDOMAIN=coreutils
LANG=fr_CH.utf8
echo $"system boot"
démarrage système
Run Code Online (Sandbox Code Playgroud)

(注意:对于这项工作,fr_CH.utf8已经在您的系统上生成了......否则您可以尝试使用自己的语言环境...或者安装locales并生成一个.)

问题:

但是如果这对于简单的字符串工作正常,那么当字符串包含一个\n(或者最坏的:一个反引号时,`事情会更复杂:

echo $"Written by %s, %s, %s,\nand %s.\n"
Written by %s, %s, %s,\nand %s.\n
Run Code Online (Sandbox Code Playgroud)

这不是参加的答案.

(Nota2:对于这项工作,必须在消息文件中准备确切的消息.mo,在此示例/测试中,我使用的是existant coreutils.mo文件,可以使用该命令取消格式化msgunfmt.)

总之,我发现进行翻译的唯一方法是:

eval echo \$\"$'Written by %s, %s, %s,\nand %s.\n'\"
Écrit par %s, %s, %s,
et %s.
Run Code Online (Sandbox Code Playgroud)

要么

msg=$'Written by %s, %s, %s,\nand %s.\n'
eval echo \$\""$msg"\"
Écrit par %s, %s, %s,
et %s.
Run Code Online (Sandbox Code Playgroud)

(你可以看到两个双引号......不是很性感......)

最后我可以:

WRITTERS=(Hans Pierre Jackob Heliott)
eval printf \$\""$msg"\" ${WRITTERS[@]}
Écrit par Hans, Pierre, Jackob,
et Heliott.
Run Code Online (Sandbox Code Playgroud)

但正如我最近听说eval是邪恶的 ...... ;-)

事实上,我没有eval运行仅使用硬编码部分的问题,但我希望能够保持这种评估并以更自然可读的方式编写这种部分.

在@techno的回答中,让我看到我的第一个想法是危险的,好像WRITTERS包含一些;ls,样本......

编辑:所以问题是:

我怎么能把它eval拿出来和/或以更性感的方式写出来

诺塔:

$ printf "I use bash %s on Debian %s\n" $BASH_VERSION $(</etc/debian_version)
I use bash 4.1.5(1)-release on Debian 6.0.6
Run Code Online (Sandbox Code Playgroud)

gni*_*urf 6

我已经使用了这个功能,这就是我想出的:你可以将换行符包括在:

$ echo $"Written by %s.
> "
Écrit par %s.
$ 
Run Code Online (Sandbox Code Playgroud)

在脚本中:

#!/bin/bash

message=$"Written by %s.
"

printf "$message" Gniourf
Run Code Online (Sandbox Code Playgroud)

该脚本将输出:

Écrit par Gniourf.
Run Code Online (Sandbox Code Playgroud)

好吧,这不是一个真正的答案,但它可能会有所帮助(至少,我们没有使用邪恶eval).

个人评论:我发现这个功能真的很笨重!