# Download and define advanced function Invoke-WithEncoding in the current session.
irm https://gist.github.com/mklement0/ef57aea441ea8bd43387a7d7edfc6c19/raw/Invoke-WithEncoding.ps1 | iex
# Download and define advanced function Debug-NativeInOutput in the current session.
irm https://gist.github.com/mklement0/eac1f18fbe0fc2798b214229b747e5dd/raw/Debug-NativeInOutput.ps1 | iex
# Outputs *already-decoded* output, so if the output *prints* fine,
# then *decoding* worked fine too.
PS> Invoke-WithEncoding { python -c "print('eé')" } -Encoding Ansi -WindowsOnly
eé
注:问题中描述的特定
pino-pretty
问题未通过以下信息解决。卢卡斯(OP)提交了一份错误报告。令人惊讶的是,你什么也得不到,但是基本的区别是:
cmd.exe
的管道执行原始数据,即字节流(接收数据的给定程序本身可能解释为文本)PowerShell的管道在与外部程序对话时,只执行文本(字符串),这有两种含义:
在将数据传输到外部程序时,文本必须编码,这是基于preference variable ^{} 中存储的字符编码发生的
从外部程序接收数据时,必须对数据进行解码,该解码基于存储在
[Console]::OutputEncoding
中的字符编码,默认情况下,该编码是系统的OEM代码页,如chcp
所示无论数据随后是在PowerShell中进一步处理还是传递到另一个外部程序,这种解码总是发生
唯一的异常是外部程序输出既没有被捕获,也没有通过管道发送,也没有重定向到文件:在这种情况下,数据直接打印到控制台(终端),但只打印在本地控制台中(当使用PowerShell远程处理与远程机器交互时,解码同样不可避免地涉及到)
python
,在这种情况下使用完全的Unicode支持,;也就是说,输出可能会打印很好,但当您尝试进一步处理它时,编码问题可能会浮出水面(...)
中;例如python -c "print('eé')"
打印的很好,但是(python -c "print('eé'))"
显示了一个编码问题;有关详细信息,请参阅底部部分控制台应用程序传统上使用活动OEM代码页进行字符编码和解码,Node.js始终使用UTF-8
因此,为了使PowerShell与Node.js程序正确通信,必须(临时)首先设置以下各项:
如果您想从根本上切换到UTF-8,或者在系统范围内(这会产生深远的影响)或者仅针对PowerShell控制台窗口,请参见this answer
顺便说一句:中继外部程序的输出永远不需要中间的
Out-String -Stream
管道段——这实际上是(代价高昂的)不可操作的,因为PowerShell默认情况下会逐行流式处理标准输出。换句话说,它对您的情况没有影响,这并不奇怪可选阅读:方便功能
Invoke-WithEncoding
和诊断功能Debug-NativeInOutput
用于特殊编码需求/诊断:如果无法将所有PowerShell控制台切换到UTF-8,和/或您需要处理使用UTF-8或活动OEM代码页以外的特定编码的“流氓”程序,您可以安装:
Invoke-WithEncoding
,它在调用外部程序时直接从this Gist临时切换到给定的编码,如下所示(我可以向您保证这样做是安全的,但您应该始终检查):Debug-NativeInOutput
,它可以直接从this Gist诊断外部程序的编码问题,如下所示(同样,您应该先检查):下面是使用
python
命令打印重音字符的示例命令与Node.js一样,Python的行为也是非标准的,尽管它没有使用UTF-8,但系统的活动代码页(而不是预期的OEM代码页)
也就是说,即使您切换PowerShell控制台UTF-8,默认情况下,与Python脚本的通信也无法正常工作,除非进行额外的工作,
Invoke-WithEncoding
可以为您封装:注意:我在这里使用Python作为示例,以说明函数是如何工作的。可以使Python使用UTF-8,即通过将环境变量
PYTHONUTF8
设置为1
或在v3.7+中通过传递参数-X utf8
(大小写完全相同)。Invoke-WithEncoding
示例:请注意,
Invoke-WithEncoding
确保对.NET字符串的实际解码发生在其输出之前,这样编码问题就不会被直接屏蔽,从而在Windows上显示输出似乎是正确的(有关更多信息,请参阅下文)-WindowsOnly
用于跨平台兼容性,并确保在这种情况下编码仅应用于Windows(在Unix上,Python使用UTF-8)Debug-NativeInOutput
示例:在PowerShell控制台处于默认状态的情况下,使用系统的OEM代码页,使用相同的Python命令,从PowerShell(Core)7.1调用,您将看到以下输出:
注意
DecodedOutput
属性,它显示了mis-解码结果,该结果基于将Python的输出解释为OEM-而不是ANSI编码:'eΘ'
。(由于该命令没有将数据管道化到Python脚本,Input*
属性为空。)相比之下,使用直接显示打印输出可以打印精细(因为Python当时-而且只有那时-使用Unicode),这隐藏了问题,但是只要您想以编程方式处理变量中的输出捕获,就可以发送到管道中的另一个命令,重定向到文件-编码问题将浮出水面
与
Invoke-WithEncoding
类似,Debug-NativeInOutput
支持-Encoding
参数,因此如果将-Encoding Ansi
传递给上面的调用,您将看到Python的输出被正确解码输出反映了这样一个事实:在PowerShell(核心)中,
$OutputEncoding
默认为UTF-8,而在Windows PowerShell中它默认为ASCII(!)。这种与控制台窗口中实际编码的不匹配是有问题的,并且this comment on GitHub issue #14945提出了一种解决方法(仅适用于PowerShell(Core))将来解决此问题相关问题 更多 >
编程相关推荐