我在Windows中设置了一个环境变量TEST=abc£
,它使用Windows-1252
代码页。现在,当我运行Perl程序test.pl
时,此环境值正确。
当我通过test2.pl
或test1.pl
从system(..)
调用另一个Perl代码 - Win32::Process
时,环境会出现乱码。
有人可以提供信息,为什么会这样解决?
我使用的perl
版本是5.8。
如果我的理解是正确的,perl
内部使用utf-8
,那么初始流程 - test1.pl
就会从Windows-1252
→utf-8
收到。当我们调用另一个进程时,我们是否应该转换回Windows-1252
代码页?
答案 0 :(得分:9)
这与Perl的内部字符串编码无关,但需要正确解码来自外部的数据。我将提供测试用例。这是西欧Windows XP上的Strawberry Perl 5.10。
test1.pl:
use Devel::Peek;
print Dump $ENV{TEST};
use Encode qw(decode);
my $var = decode 'Windows-1252', $ENV{TEST};
print Dump $var;
system "B:/sperl/perl/bin/perl.exe B:/test2.pl";
test2.pl:
use Devel::Peek;
print Dump $ENV{TEST};
use Encode qw(decode);
my $var = decode 'IBM850', $ENV{TEST};
# using Windows-1252 again is wrong here
print Dump $var;
执行:
> set TEST=abc£
> B:\sperl\perl\bin\perl.exe B:\test1.pl
输出(缩短):
SV = PVMG(0x982314) at 0x989a24
FLAGS = (SMG, RMG, POK, pPOK)
PV = 0x98de0c "abc\243"\0
SV = PV(0x3d6a64) at 0x989b04
FLAGS = (PADMY, POK, pPOK, UTF8)
PV = 0x9b5be4 "abc\302\243"\0 [UTF8 "abc\x{a3}"]
SV = PVMG(0x982314) at 0x989a24
FLAGS = (SMG, RMG, POK, pPOK)
PV = 0x98de0c "abc\243"\0
SV = PV(0x3d6a4c) at 0x989b04
FLAGS = (PADMY, POK, pPOK, UTF8)
PV = 0x9b587c "abc\302\243"\0 [UTF8 "abc\x{a3}"]
Windows会对文本环境(IBM850)使用与图形环境(Windows-1252)不同的编码这一事实而感到困惑。专家必须解释这一现象的更深层细节。
编辑:
有可能启发式(意味着它有时会做不正确的事,特别是对于这样的短字符串)确定编码。最佳通用解决方案是Encode::Detect/Encode::Detect::Detector,它基于Mozilla nsUniversalDetector。
有一些方法可以隐含地解码外部数据,例如open
pragma/IO layers和-C
switch,但它们只处理文件流和程序参数。截至目前,必须从环境中明确解码。无论如何,我更喜欢那样,明确表示你认为topic通过的维护程序员。