IPC::Open3 转换字符编码

Posted

技术标签:

【中文标题】IPC::Open3 转换字符编码【英文标题】:IPC::Open3 converting character encoding 【发布时间】:2015-12-18 08:10:39 【问题描述】:

我观察到 IPC::Open3 参数作为脚本的一部分出现的奇怪行为。

我给出一个包含 ISO-8859-15 的字符串。就在调用 open3() 之前(字面意思是之前的语句),字符串是正确的(使用 printData::Dumper 验证)。

然而,一旦子进程启动,参数现在是 UTF-8 编码的。我已经使用所需的可执行文件(freebcp)和包装脚本验证了这一点。我最终编写了一个包装脚本,将所有参数转换回 ISO-8859-15。

是什么导致了这种行为? LANG 设置为 en_AU.ISO-8859-15。它在其他主机上正常工作。我找不到对 binmode() 的任何引用

【问题讨论】:

"它可以在其他主机上正常工作。" - 那么也许你也应该向我们描述它工作的主机,以及它不工作的主机。 进行转换的是 RHEL 并且使用 perl 5.20.2 的编译版本我的开发环境是使用 stock perl 的 Ubuntu 14.04 任何use open:encoding:locale,或-C 选项到perl? Perl5 默认不做任何字符集转换——默认一直是哑二进制模式。但在你的情况下,数据似乎不是二进制的。它们是 Perl 中的 Unicode(因此在写出时会进行转换),这意味着您在某处告诉 Perl 从二进制中解码数据。 续。如果是这种情况,那么您可能应该明确告诉 Perl 在将数据写入open3 文件句柄时转换它们。 我还应该指出,仅使用 open3() 的测试脚本不会进行转换。很奇怪 【参考方案1】:

我有一个包含 ISO-8859-15 的字符串。就在调用open3() 之前(字面意思是之前的语句),字符串是正确的(用printData::Dumper 验证)。

然而,一旦子进程启动,参数现在是 UTF-8 编码的。

LANG 设置为 en_AU.ISO-8859-15。

默认情况下,Perl5 不进行任何编码转换:字符串被视为哑字节数组。

直到你告诉 Perl 字符串包含 Unicode,例如通过调用decode(),或从附加了编码层的文件句柄中读取字符串(通过binmode(),或通过open() 标志,或通过use open:encoding/:locale,或通过命令行与-C 开关。)

因为你有 ISO-8859-15 中的字符串,但它以 UTF-8 输出,这意味着 Perl 知道你的字符串的编码。不知何故,您告诉 Perl 字符串的编码,它已将其转换为 Unicode,它在内部使用 UTF-8 表示。现在似乎打印到open3() 文件句柄的UTF-8。

作为一种可能的解决方案,在输出字符串之前,您应该尝试将字符串显式转换为所需的编码。

附:使用utf8::is_utf8() 函数,您可以尝试调试/查找您的字符串何时/如何转换为 Unicode,以及它们是否真的是 Unicode。

【讨论】:

以上是关于IPC::Open3 转换字符编码的主要内容,如果未能解决你的问题,请参考以下文章

c++字符编码转换

字符串编码转换

如何对mysql中的字符进行编码转换

在Linux如何让更改文件的字符编码

字符编码转换

【高分,急!】linux下字符编码转换问题