我在 Windows 中将环境变量设置为 TEST=abc£
,它使用 Windows-1252
代码页。现在,当我运行一个 Perl 程序 test.pl
时,这个环境值就正确了。
当我通过 system(..)
或 Win32 从
,环境来了乱码。 test1.pl
调用另一个 Perl 代码 - test2.pl
::Process
有人可以提供信息为什么会这样以及解决方法吗?
我使用的 perl
版本是 5.8。
如果我的理解是正确的,perl
内部使用 utf-8
,所以初始进程 - test1.pl
直接从 Windows-1252
→ utf-8
。当我们调用另一个进程时,我们是否应该转换回 Windows-1252
代码页?
最佳答案
这与 Perl 的内部字符串编码无关,但需要正确解码来自外部的数据。我会提供测试用例。这是西欧 Windows XP 上的 Strawberry Perl 5.10。
测试1.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";
测试2.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 ,但是它们只处理文件流和程序参数。截至目前,必须明确解码来自环境的信息。无论如何,我更喜欢这样,explicite 向维护程序员展示了你认为 topic通过。
关于windows - 如何在 Perl 中正确使用编码为 Windows-1251 的环境变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2437877/