【发布时间】:2019-03-27 06:05:00
【问题描述】:
基本上,我编写了一个 Perl 脚本,它为 Powershell 创建了一个编码命令并尝试运行它。在对它进行 base64 编码之前,我必须将命令字符串显式转换为 utf-16。我想知道为什么这就是我必须让脚本正常工作的全部。默认情况下,Windows* 上的 Perl 在运行与控制台以及可能与文件系统交互的“普通”程序时会执行哪些转换?例如,是否转换了 argv?标准输入/标准输出是否转换?文件 IO 是否经过转换?
✱ 特别是 Strawberry Perl 发行版,以防 ActivePerl 做一些不同的事情
我正在尝试编写一个调用许多 PowerShell 片段并依赖于 Strawberry Perl 分发的 Perl 脚本。
PowerShell 有一个 -encodedCommand 标志,它接受 base64 编码的字符串,然后对其进行处理,相当方便。这有助于避免与引用相关的问题。
我尝试了可能可行的最简单的方法。
// powersheller.pl
#! /usr/bin/env perl
use strict;
use warnings;
use MIME::Base64;
use Encode qw/encode decode/;
use vars ('$powershell_command');
sub run_powershell_fragment {
my ($contents) = @_;
my $encoded = encode_base64($contents);
printf "encoded: %s\n", $encoded;
return `powershell.exe -noprofile -encodedCommand $encoded`;
}
printf "%s\n---\n", run_powershell_fragment($powershell_command);
BEGIN {
$powershell_command = <<EOF
echo "hi"
EOF
}
然后运行它。这是在 powershell 窗口中运行 perl 脚本时...标准输出通道 (?) 的输出。
PS C\...> perl .\powersheller.pl
encoded: ZWNobyAiaGkiCQo=
Redundant argument in printf at .\powersheller.pl line 18.
?????? : The term '??????' is not recognized as the name of a cmdlet, function, script file, or operable program.
---
这看起来像是编码问题。我猜 Perl 默认使用类似于 utf-8 的东西,而 powershell 期望使用 utf16-le 或类似的东西。
sub run_powershell_fragment {
my ($contents) = @_;
my $utf16_le_contents = encode("utf-16le", $contents);
my $encoded = encode_base64($utf16_le_contents);
printf "encoded: %s\n", $encoded;
return `powershell.exe -noprofile -encodedCommand $encoded`;
}
从技术上讲,使用"ucs-2le" 也可以。不知道哪个合适。
无论如何,在插入额外转换的情况下,程序按预期运行。
PS C:\...> perl .\powersheller.pl
encoded: ZQBjAGgAbwAgACIAaABpACIACQAKAA==
hi
---
为什么这就是我需要做的一切? Perl 是否处理与 argv 和 stdout &c 相关的转换?
【问题讨论】:
标签: windows powershell perl unicode