IPC::Open3 转换字符编码
Posted
技术标签:
【中文标题】IPC::Open3 转换字符编码【英文标题】:IPC::Open3 converting character encoding 【发布时间】:2015-12-18 08:10:39 【问题描述】:我观察到 IPC::Open3 参数作为脚本的一部分出现的奇怪行为。
我给出一个包含 ISO-8859-15 的字符串。就在调用 open3() 之前(字面意思是之前的语句),字符串是正确的(使用 print
和 Data::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()
之前(字面意思是之前的语句),字符串是正确的(用Data::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 转换字符编码的主要内容,如果未能解决你的问题,请参考以下文章