问题描述
bash 中有一个很好的特性,关于本地化(语言翻译):
There is a nice feature in bash, about localization (language translation):
TEXTDOMAIN=coreutils
LANG=fr_CH.utf8
echo $"system boot"
démarrage système
(注意:对于这项工作,fr_CH.utf8
已经在您的系统上生成...否则您可以尝试使用自己的locale... 或安装 locales
并生成一个.)
(Nota: For this work, fr_CH.utf8
was already generated on your system... Else you may try with your own locale... or install locales
and generate one.)
问题:
但是如果这适用于简单的字符串,当字符串包含 (或更糟糕的是:反引号
`
事情会更复杂:
But if this work fine with simple strings, when string contain a (or worst: a backtick
`
things are more complicated:
echo $"Written by %s, %s, %s,
and %s.
"
Written by %s, %s, %s,
and %s.
这是无人参与的答案.
(Nota2: 对于这项工作,exact 消息必须在 .mo
消息文件中准备好,在这个示例/测试中,我使用现有的 coreutils.mo
文件,可以使用命令 msgunfmt
将其格式化.)
(Nota2: For this work, exact message has to be prepared in .mo
message file, in this sample/test, I use existant coreutils.mo
files, which could be unformated with the command msgunfmt
.)
我发现做翻译的唯一方法是:
At all, the only way I've found to do the translation is:
eval echo $"$'Written by %s, %s, %s,
and %s.
'"
Écrit par %s, %s, %s,
et %s.
或
msg=$'Written by %s, %s, %s,
and %s.
'
eval echo $""$msg""
Écrit par %s, %s, %s,
et %s.
(你可以看到两个双引号......不是很性感......)
(You could see two double quotes... not very sexy...)
我终于可以了:
WRITTERS=(Hans Pierre Jackob Heliott)
eval printf $""$msg"" ${WRITTERS[@]}
Écrit par Hans, Pierre, Jackob,
et Heliott.
但我最近听说 eval 是邪恶的... ;-)
But as I've heard recently that eval is evil... ;-)
事实上,我对 仅使用硬编码部分 运行的 eval
没有任何问题,但我希望有一种方法可以将这个 eval 排除在外并以更自然或可读的方式写出这类部分.
In fact, I don't have problem with an eval
that's run with only hard coded part, but I would appreciate a way to keep this eval out and to write this kind of part in a more natural or readable manner.
@techno 的回答让我看到我的第一个想法是 危险 好像 WRITTERS
包含一些 ;ls
,因为样品...
At all @techno 's answer let me see that my first idea is something dangerous as if WRITTERS
contain some ;ls
, for sample...
所以问题是:
我怎样才能不让这个 eval
出来和/或以更性感的方式写这个
How could I keep this eval
out and/or write this in a more sexy fashion
注意:
$ printf "I use bash %s on Debian %s
" $BASH_VERSION $(</etc/debian_version)
I use bash 4.1.5(1)-release on Debian 6.0.6
推荐答案
如果使用 eval
对任意变量不好,有一种方法可以做到这一点只有在调用/需要时,仅在消息部分运行 eval
:
If using eval
is bad with arbitrary variables, there is a way to do this only when called/needed, in running eval
only on message part:
function lPrintf() {
local sFormat="$(
eval 'echo $"'"${1}"'"'.
)"
shift
printf "${sFormat%.}" $@
}
lPrintf "system boot"
démarrage système
lPrintf $'Written by %s, %s, %s,
and %s.
' techno moi lui-même bibi
Écrit par techno, moi, lui-même,
et bibi.
( 翻译字符串末尾的点确保整个字符串,包括前导换行符,传递给变量 sFormat
.它们将与 ${sFormat%.})
( The dot at end of translated string ensure that whole string, including leading line-break, where passed to variable
sFormat
. They will be dropped with ${sFormat%.}
)
这篇关于bash 本地化不适用于多行字符串(使用强语法或通过 `eval`)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!