我有一个生成 utf8 输出的 perl 脚本。我尝试使用 Set-Content 编写一个 utf8 文件,如Powershell 推翻了 Perl binmode 吗?。
perl -S testbinmode.pl | Set-Content "binmode.txt" -Encoding Byte
产生错误
“Set-Content:无法继续进行字节编码。使用字节编码时,内容必须是字节类型。”
perl -S testbinmode.pl | Set-Content "binmode.txt" -Encoding UTF8
不会产生错误消息,但它也不会写入正确的 utf8 文件。
perl 脚本的输出在 Powershell 窗口中正确显示。将该输出写入 utf8 编码文件的正确方法是什么?
谢谢。
更新:我已经看到了很多对这个问题和类似问题的回应,在上面引用的链接中,以及https://stackoverflow.com/questions/40098771/changing-powershells-default-output-encoding-to-utf-8。它们似乎都不起作用,这让我相信它们都没有真正被测试过。已测试需要一种将 CLI 程序的 UTF8 文本输出重定向到文件的方法。谢谢。
以下是 perl 测试脚本:
use strict;
use warnings;
use utf8;
binmode(STDOUT, ":utf8");
print("The Crüxshadows");
答案1
确保 PowerShell 在与外部程序通信时使用 UTF-8。(内置 cmdlet 已默认使用 UTF-8。)这需要将[console]::InputEncoding
和设置[console]::OutputEncoding
为UTF-8
。
在我的 Windows 10 系统上,PowerShell 默认使用代码页 437:
PS C:\Users\Me> [Console]::OutputEncoding
IsSingleByte : True
EncodingName : OEM United States
WebName : ibm437
HeaderName : ibm437
BodyName : ibm437
Preamble :
WindowsCodePage :
IsBrowserDisplay :
IsBrowserSave :
IsMailNewsDisplay :
IsMailNewsSave :
EncoderFallback : System.Text.InternalEncoderBestFitFallback
DecoderFallback : System.Text.InternalDecoderBestFitFallback
IsReadOnly : False
CodePage : 437
我们使用以下命令为当前 PowerShell 会话修复此问题:
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
(请参阅上面链接的 github.com 问题以了解如何保留此更改。)
PS C:\Users\Me> [Console]::OutputEncoding
Preamble :
BodyName : utf-8
EncodingName : Unicode (UTF-8)
HeaderName : utf-8
WebName : utf-8
WindowsCodePage : 1200
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.EncoderReplacementFallback
DecoderFallback : System.Text.DecoderReplacementFallback
IsReadOnly : False
CodePage : 65001
Windows 7 及更高版本(即所有受支持的 Windows 版本)均具有代码页 65001,作为 UTF-8 的同义词
——https://en.wikipedia.org/wiki/UTF-8
现在您的脚本已按预期工作。
perl .\testbinmode.pl | Set-Content "binmode.txt" -Encoding UTF8
在 PowerShell 5.1 和 7.1 上测试成功。
如果您更喜欢无 BOM:
perl .\testbinmode.pl | Set-Content "binmode.txt" -Encoding UTF8NoBOM
在 PowerShell 7.1 上测试成功。(该UTF8NoBOM
编码是在 PowerShell 6 中引入的。)