注意:下面提供的信息没有解决问题中描述的具体 "pino-pretty" 问题。Lukas(提问者)已经在这里提交了错误报告
here。
令人惊讶的是,你什么都没得到,但是根本的区别是:
尽管控制台应用程序传统上使用活动的 OEM 代码页来进行字符编码和解码,但 Node.js 总是使用 UTF-8。
因此,为了使 PowerShell 能够与 Node.js 程序正常通信,您必须(暂时)首先设置以下内容:
$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
如果您想要根本地切换到UTF-8,无论是系统范围内(这将产生深远的影响)还是仅限于PowerShell控制台窗口,请参阅此答案。
顺便说一句:中间的
Out-String -Stream
管道段对于传递外部程序的输出是不必要的,因为逐行流式传输stdout输出是PowerShell的默认行为。换句话说,在你的情况下,这没有什么意义,实际上只是一个(代价高昂的)空操作。
可选阅读:方便的函数Invoke-WithEncoding
和诊断函数Debug-NativeInOutput
用于临时编码需求/诊断:
如果将所有PowerShell控制台切换为UTF-8不是一个选择,或者您需要处理使用特定编码而不是UTF-8或活动OEM代码页的“流氓”程序,您可以安装:
- 函数
Invoke-WithEncoding
,它在调用外部程序时临时切换到给定的编码,直接从this Gist安装如下(我可以向您保证这样做是安全的,但您应该始终进行检查):
irm https://gist.github.com/mklement0/ef57aea441ea8bd43387a7d7edfc6c19/raw/Invoke-WithEncoding.ps1 | iex
- 功能
Debug-NativeInOutput
,可以直接从this Gist(再次强调,你应该先检查)中获取,用于帮助诊断与外部程序相关的编码问题。
irm https://gist.github.com/mklement0/eac1f18fbe0fc2798b214229b747e5dd/raw/Debug-NativeInOutput.ps1 | iex
下面是使用python命令打印重音字符的示例命令。
与Node.js类似,Python的行为是非标准的,虽然它不使用UTF-8,而是使用系统的活动ANSI(!)代码页(而不是预期的OEM代码页)。
也就是说,即使您将PowerShell控制台切换为UTF-8,在默认情况下与Python脚本的通信也不会正常工作,除非进行额外的努力,而Invoke-WithEncoding可以为您封装这些操作:
注意:我在这里使用Python作为示例来说明这些函数的工作原理。实际上可以让Python使用UTF-8,具体方法是通过将环境变量PYTHONUTF8设置为1,或者在v3.7+版本中通过传递参数-X utf8(区分大小写)。
Invoke-WithEncoding
示例:
PS> Invoke-WithEncoding { python -c "print('eé')" } -Encoding Ansi -WindowsOnly
eé
请注意,`Invoke-WithEncoding` 确保在输出之前对 .NET 字符串进行了实际解码,以防止编码问题在 Windows 上的直接显示输出中被意外掩盖(有关更多信息,请参见下文)。
`-WindowsOnly` 用于跨平台兼容性,并确保在此情况下仅在 Windows 上应用编码(在 Unix 上,Python 使用 UTF-8)。
Debug-NativeInOutput
示例:
使用默认的PowerShell控制台,使用系统的OEM代码页,在相同的Python命令调用下,您将看到以下输出,从PowerShell (Core) 7.1中调用:
PS> Debug-NativeInOutput { python -c "print('eé')" }
![Debug-NativeInOutput](https://istack.dev59.com/FuwV9.webp)
注意
DecodedOutput
属性,它显示了基于将Python的输出解释为
OEM而不是ANSI编码的结果:
'eΘ'
。(
Input*
属性为空,因为该命令没有涉及将数据通过管道传递给Python脚本。)
相比之下,使用
直接打印到显示器时,输出会正常打印(因为Python只有在这种情况下才使用Unicode),这样就
隐藏了问题,但是一旦你想要
以编程方式处理输出 - 将其捕获到变量中,发送到管道中的另一个命令,或者重定向到文件中 - 编码问题就会浮出水面。
与
Invoke-WithEncoding
类似,
Debug-NativeInOutput
也支持
-Encoding
参数,因此如果你在上述调用中传递
-Encoding Ansi
,你会看到Python的输出被正确解码。
输出反映了在PowerShell(Core)中,默认的
$OutputEncoding
为UTF-8,而在Windows PowerShell中,默认为ASCII(!)。这与控制台窗口中实际生效的编码不匹配,这是一个问题,
GitHub问题#14945上的评论提出了一种未来解决此问题的方法(仅适用于PowerShell(Core))。