这个问题的根本原因是我尝试为 Perl 的新选项/参数处理模块 ( OptArgs ) 编写测试。这当然涉及解析 @ARGV
我正在根据对 this 的答案进行操作问题。这在定义了 I18N::Langinfo::CODESET 的系统上运行良好 [1]。
在 langinfo(CODESET)
的系统上不可用 我想至少根据观察到的行为尽最大努力。但是到目前为止,我的测试表明某些系统我什至无法将 unicode 参数正确地传递给外部脚本。
我已经设法在“test_script”是一个仅执行print Dumper(@ARGV)
的Perl脚本的各种系统上运行类似以下的东西。 :
use utf8;
my $utf8 = '¥';
my $result = qx/$^X test_script $utf8/;
我发现在 FreeBSD 上 test_script 接收可以解码为 Perl 内部格式的字节。但是在 OpenBSD 和 Solaris 上 test_script 似乎得到了字符串
"\x{fffd}\x{fffd}"
其中仅包含 unicode 替换字符(两次?)。我不知道
qx
背后的机制运算符(operator)。我猜是exec
's 或 shells,但与文件句柄不同(我可以对它们进行 binmode 编码),我不知道如何确保它符合我的要求。与 system()
相同对于这个问题。所以我的问题是我在上面做错了什么?否则 Perl 或 shell 或 OpenBSD 和 Solaris 上的环境有什么不同?[1] 实际上我认为到目前为止,根据 CPAN 测试人员的结果,这只是 Linux。
更新(x2):我目前通过 cpantester 的设置运行以下命令来测试 Schwern 的假设:
use strict;
use warnings;
use Data::Dumper;
BEGIN {
if (@ARGV) {
require Test::More;
Test::More::diag( "\npre utf8::all: "
. Dumper( { utf8 => $ARGV[0], bytes => $ARGV[1] } ) );
}
}
use utf8;
use utf8::all;
BEGIN {
if (@ARGV) {
Test::More::diag( "\npost utf8::all: "
. Dumper( { utf8 => $ARGV[0], bytes => $ARGV[1] } ) );
exit;
}
}
use Encode;
use Test::More;
my $builder = Test::More->builder;
binmode $builder->output, ':encoding(UTF-8)';
binmode $builder->failure_output, ':encoding(UTF-8)';
binmode $builder->todo_output, ':encoding(UTF-8)';
my $utf8 = '¥';
my $bytes = encode_utf8($utf8);
diag( "\nPassing: " . Dumper( { utf8 => $utf8, bytes => $bytes, } ) );
open( my $fh, '-|', $^X, $0, $utf8, $bytes ) || die "open: $!";
my $result = join( '', <$fh> );
close $fh;
ok(1);
done_testing();
当它们通过时,我会在各种系统上发布结果。对此的有效性和正确性的任何评论将不胜感激。请注意,它不是一个有效的测试。上述的目的是能够比较在不同系统上接收到的内容。
分辨率 : 真正的潜在问题原来是我的问题中没有解决的问题,也没有由 Schwern 在下面的回答中解决。我发现一些 cpantesters 机器只安装了/可用的 ascii 语言环境。我不应该期望在这种环境中将 UTF-8 字符传递给程序的任何尝试都能正常工作。所以最后我的问题是无效的测试条件,而不是无效的代码。
到目前为止,我没有看到任何迹象表明
qx
运算符或 utf8::all
模块对如何将参数传递给外部程序有任何影响。关键组件似乎是 LANG
和/或 LC_ALL
环境变量,以通知外部程序它们正在运行的语言环境。顺便说一句,我最初的断言是我的代码在定义了 I18N::Langinfo::CODESET 的所有系统上工作是不正确的。
最佳答案
qx
调用外壳,它可能会干扰。
为避免这种情况,请使用 utf8::all打开所有 Perl Unicode voodoo。然后使用 open
函数打开一个管道到你的程序,避开 shell。
use utf8::all;
my $utf8 = '¥';
open my $read_from_script, "-|", "test_script", $utf8;
print <$read_from_script>,"\n";
关于perl - 在 Perl 中,如何将 unicode 参数传递给外部命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11111735/