如何在PowerShell中将Unicode传递给本地应用程序

6 投票
1 回答
1100 浏览
提问于 2025-04-19 13:43

我有一个用Python写的本地程序,它需要从标准输入(stdin)接收数据。举个简单的例子,

#!python3
import sys
with open('foo.txt', encoding='utf8') as f:
    f.write(sys.stdin.read())

我想通过标准输入把一个(PowerShell)字符串传给这个程序。Python会根据环境变量$env:PYTHONIOENCODING中指定的编码来读取标准输入,我通常会把它设置为UTF8(这样就不会出现编码错误)。

但是无论我怎么做,字符总是会出现乱码。我在网上查了很多资料,看到有人建议更改[Console]::InputEncoding[Console]::OutputEncoding,或者使用chcp命令,但似乎都没有效果。

这是我的基本测试:

PS >[Console]::OutputEncoding.EncodingName
Unicode (UTF-8)
PS >[Console]::InputEncoding.EncodingName
Unicode (UTF-8)
PS >$env:PYTHONIOENCODING
utf-8
PS >python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())"
´╗┐?

PS >chcp 1252
Active code page: 1252
PS >python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())"
?

PS >chcp 65001
Active code page: 65001
PS >python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())"
 ?

我该如何解决这个问题呢?

我甚至无法解释这里发生了什么。基本上,我希望这个测试(python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())")能输出一个欧元符号。为了理解为什么会这样,我需要做一些必要的调整让它正常工作 :-) (因为这样我就能把这些知识应用到我的实际场景中,也就是能够编写有效的Python程序流水线,当遇到Unicode字符时不会出错)。

1 个回答

6

感谢mike z,下面的代码可以正常工作:

$OutputEncoding = [Console]::OutputEncoding = (new-object System.Text.UTF8Encoding $false)
$env:PYTHONIOENCODING = "utf-8"
python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())"

这里需要用到new-object,这样才能得到没有BOMUTF-8编码。$OutputEncoding这个变量和[Console]::OutputEncoding这两个都需要设置好。

我还是不太明白这两种编码值有什么区别,以及为什么它们会被设置成不同的值(这似乎是默认情况)。

撰写回答