作者:手机用户2502907815 | 来源:互联网 | 2023-10-09 21:26
如果我运行这样的命令:
Write-Output March > a.txt
我得到这个结果:
U+FEFF
M U+004D
a U+0061
r U+0072
c U+0063
h U+0068
U+000D
n U+000A
我不想要 BOM。我尝试了不同的操作,如下所示:
$OutputEncoding = [System.Text.UTF8Encoding]::new($false)
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
[Console]::InputEncoding = [System.Text.UTF8Encoding]::new($false)
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)
但他们似乎都没有解决这个问题。注意我使用的是 PowerShell 5.1。我确实看到了一些类似的问题,但与此不完全相同,因为他们正在处理管道和外部命令。
回答
tl;博士
如果您希望 Windows PowerShell 的>
运算符和 cmdletOut-File
输出无BOM 的UTF-8,您唯一的选择是更改为该编码系统范围:
否则,您必须直接使用 .NET API - 请参阅此问题的答案- 或围绕它们编写一个 PowerShell 友好的包装器 - 请参阅此答案。
或者,您可以安装跨平台PowerShell [Core] v6+版本,该版本始终默认为无 BOM 的 UTF-8。
在 Windows 10 上,您可以将 Windows PowerShell默认设置为无 BOM 的 UTF-8 - 假设您愿意在系统范围内更改为这种编码:
有了这个效果:
所有文件写入[1]具有一个视窗PowerShell命令-Encoding
参数然后将默认为BOM-少UTF-8(Default
表示活性ANSI代码页,那么这将是65001
,即BOM-少UTF-8) -特别是包括>
/ Out-File
/ Set-Content
.
然后,Windows PowerShell 还会将无BOM 文件读取为 UTF-8,包括源代码和通过Get-Content
; 通常,Windows PowerShell 根据系统区域设置适当的 ANSI代码页解释无 BOM 文件(而 PowerShell [Core] v6+ 假定为 UTF-8)。
由于 OEM 代码页是无 BOM 的 UTF-8(反映在chcp.com
报告中65001
),PowerShell 也将使用无 BOM 的 UTF-8:
- 解释通过其 CLI 从外部接收的数据时。
- 解释从 PowerShell 会话内的外部程序接收的数据时。
$OutputEncoding
上面的分配还确保 PowerShell将数据作为无 BOM 的 UTF-8发送到外部程序。(幸运的是,这个首选项变量现在在 PowerShell [Core] v6+ 中默认为无 BOM 的 UTF-8。)
请注意,上述内容还使所有PowerShell [Core] v6+控制台窗口在所有方面都使用无 BOM 的 UTF-8,只是您不需要$PROFILE
添加(尽管它们没有危害)。
背景资料:
至于你尝试了什么:
您尝试的属性和变量仅与 PowerShell(在两个版本中)与外部程序通信的方式有关:
$OutputEncoding
确定 PowerShell 在通过管道向外部程序(后者可以通过 stdin(标准输入)读取数据)发送数据时使用的编码。
[Console]::OutputEncoding
确定 PowerShell 在解释从外部程序接收到的输出时使用的编码。
[Console]::InputEncoding
是编码时PowerShell使用它接收数据从外部,当它的CLI被调用。
- 警告:在这种情况下,您不能在PowerShell 会话中更改此编码,因为那为时已晚。
- 它必须由设置来电显示,前调用的PowerShell命令行,从
cmd.exe
最容易做用chcp 65001
(见警告再次呼吁chcp
从内部PowerShell的下面)。虽然这不可避免地将两者 [Console]::InputEncoding
和[Console]::OutputEncoding
,也就是通常需要。
笔记:
在Windows中,[Console]::OutputEncoding
并[Console]::InputEncoding
在默认情况下反映的遗留系统区域设置的OEM代码页的编码,通过报告chcp.com
; 在类 Unix 平台(PowerShell [Core] v6+)上,它是(现在几乎无一例外)(无 BOM)UTF-8
由于缓存这些 .NET 属性中的编码,您不能chcp.com
从PowerShell内部使用来更改这些属性 - 而是直接分配所需的编码。
有关更多信息,请参阅此答案,其中讨论了如何使 Windows 上的控制台窗口对外部程序始终使用无 BOM 的 UTF-8 。
[1] 从技术上讲,此首选项也适用于文件读取cmdlet,这对于无 BOM 的文件既不是绝对必要的,也不会对带有BOM 的文件造成任何损害- 即使该 BOM 指示 UTF-16 或 UTF- 32 编码 - 因为 BOM 总是覆盖-Encoding
参数。
[2] 不幸的是,在 Windows PowerShell 中,不同 cmdlet 的默认编码差异很大 - 请参阅此答案的底部部分。