如何在没有 BOM 的情况下重定向 PowerShell 中的输入?

2023-11-23

我正在尝试通过以下方式重定向 PowerShell 中的输入:

Get-Content input.txt | my-program args

问题是管道 UTF-8 文本前面带有 BOM (0xEFBBBF),而我的程序无法正确处理它。

一个最小的工作示例:

// File: Hex.java
import java.io.IOException;

public class Hex {
    public static void main(String[] dummy) {
        int ch;
        try {
            while ((ch = System.in.read()) != -1) {
                System.out.print(String.format("%02X ", ch));
            }
        } catch (IOException e) {
        }
    }
}

然后在 PowerShell 中:

javac Hex.java
Set-Content textfile "ABC" -Encoding Ascii
# Now the content of textfile is 0x41 42 43 0D 0A
Get-Content textfile | java Hex

或者简单地

javac Hex.java
Write-Output "ABC" | java Hex

无论哪种情况,输出都是EF BB BF 41 42 43 0D 0A.

如何在没有 0xEFBBBF 的情况下将文本通过管道传输到程序中?


Note:
The following contains general information that in a normally functioning PowerShell environment would explain the OP's symptom. That the solution doesn't work in the OP's case is owed to machine-specific causes that are unknown at this point.
This answer is about sending BOM-less UTF-8 to an external program; if you're looking to make your PowerShell console windows use UTF-8 in all respects, see this answer.

确保您的 Java 程序接收到 UTF-8 编码的输入无物料清单, 你必须设置$OutputEncoding to a System.Text.UTF8Encoding这样做的实例not发出 BOM:

# Assigns UTF-8 encoding *without a BOM*.
# PowerShell uses this encoding to encode data piped to external programs.
# $OutputEncoding defaults to ASCII(!) in Windows PowerShell, and more sensibly
# to BOM-*less* UTF-8 in PowerShell [Core] v6+
$OutputEncoding = [Text.UTF8Encoding]::new($false)

Caveats:

  • 不要使用看似等效的New-Object Text.Utf8Encoding $false,因为,由于中描述的错误GitHub 问题 #5763,如果你分配给$OutpuEncoding在非全局范围内,例如在script。在 PowerShell v4 及更低版本中,使用
    (New-Object Text.Utf8Encoding $false).psobject.BaseObject作为解决方法。

  • Windows 10 版本 1903 及更高版本让你将 BOM-less UTF-8 设置为系统范围默认值编码(尽管请注意,该功能仍然被分类为beta自版本 20H2 起) - 请参阅这个答案; [PowerShell 7.1 中已修复] 在 PowerShell [核心] v7.0 及更高版本中, 启用此功能后,上述技术是not有效,由于假定的 .NET Corebug导致 UTF-8 BOMalways无论您设置什么编码,都会被发出$OutputEncoding到(该错误可能与GitHub 问题 #28929); 唯一的解决方案是关闭该功能off,如图所示imgx64 的回答.

相比之下,如果您使用[Text.Encoding]::Utf8,你会得到一个System.Text.Encoding.UTF8实例with BOM- 我怀疑你的情况就是这样。


请注意,此问题与任何源编码无关file阅读者Get-Content, 因为通过 PowerShell 管道发送的绝不是流原始字节, but .NET 对象,在这种情况下Get-Content意味着.NETstrings已发送 (System.String,内部是 UTF-16 代码单元的序列)。

因为你正在通过管道传输到外部程序(在您的情况下是一个 Java 应用程序),PowerShell 对发送给它的(按需字符串化)对象进行字符编码偏好变量$OutputEncoding,结果编码就是外部程序接收的内容。

也许令人惊讶的是,尽管 BOM 通常只使用in files, PowerShell 尊重分配给的编码的 BOM 设置$OutputEncoding also 在管线中,将其添加到发送的第一行(仅)。

请参阅底部部分这个答案有关 PowerShell 如何处理外部程序的管道输入和输出的更多信息,包括如何it is [Console]::OutputEncoding当 PowerShell 解释收到的数据时这很重要from外部程序.


要使用示例程序说明差异(请注意如何使用 PowerShell 字符串文字作为输入就足够了;无需从文件中读取):

# Note the EF BB BF sequence representing the UTF-8 BOM.
# Enclosure in & { ... } ensures that a local, temporary copy of $OutputEncoding
# is used.
PS> & { $OutputEncoding = [Text.Encoding]::Utf8; 'hö' | java Hex }
EF BB BF 68 C3 B6 0D 0A

# Note the absence of EF BB BF, due to using a BOM-less
# UTF-8 encoding.
PS> & { $OutputEncoding = [Text.Utf8Encoding]::new($false); 'hö' | java Hex }
68 C3 B6 0D 0A

In Windows PowerShell, where $OutputEncoding默认为 ASCII(!),默认情况下您会看到以下内容:

# The default of ASCII(!) results in *lossy* encoding in Windows PowerShell.
PS> 'hö' | java Hex 
68 3F 0D 0A

注意3F代表字面意思?字符,即非 ASCII 字符ö字符也被音译,因为它没有 ASCII 表示;换句话说:信息丢失.

PowerShell [核心] v6+现在明智地默认为无 BOM UTF-8,因此默认行为符合预期。
虽然 BOM-less UTF-8 是 PowerShell [Core] 的持续的默认值,也适用于读取和写入文件的 cmdletWindows [Console]::OutputEncoding从 v7.0 开始,默认情况下仍然反映活动的 OEM 代码页,因此要正确捕获来自 UTF-8 发射外部程序的输出,必须将其设置为[Text.UTF8Encoding]::new($false)以及 - 参见GitHub 问题 #7233.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在没有 BOM 的情况下重定向 PowerShell 中的输入? 的相关文章

  • 将 Powershell 对象的类型名称从 PSCustomObject 更改为我选择的名称?

    我有一个使用自定义对象的脚本 我用这样的伪构造函数创建它们 function New TestResult trProps name repo vcs Skipped clean New StageResult This is anothe
  • 使用 shell_exec 将 PHP 转换为 Powershell

    如果我运行 output shell exec powershell get service dhcp 我得到了 dhcp 服务的完美输出 显示正在运行 但如果我运行 output shell exec powershell get use
  • 通过快捷方式更改桌面的 Powershell 脚本

    关于为什么从 w in PS 运行时有效 但从定义为以下的快捷方式运行时无效的任何想法和建议 SystemRoot system32 WindowsPowerShell v1 0 powershell exe File C Users bi
  • 将服务器添加到 SQL Management Studio

    我想将不同服务器上的一堆 SQL 2000 2005 的混合 服务器实例添加到我的 SSMS SQL Managment Studio 注册服务器 我正在遵循本教程here http sev17 com 2008 12 registerin
  • .properties 或 JSP 编码有问题

    我有jsp文件
  • 如何使用 Apache Ant 将 Java 文件编码为 UTF-8?

    在我的 build xml 文件中 我通过 cxf 获取一些 Java 文件 其中一些 Java 文件需要使用 UTF 8 进行编码 如何使用 Ant 将编码更改为 UTF 8 PS 我找到了如何将 javac 的编码设置为 UTF 8 的
  • 替换第二个和第三个下划线之间的任何内容

    我有一个 PowerShell 脚本行 它用 替换 删除 第二个和第三个下划线之间的字符 get childitem pdf rename item newname name replace p L p L 例子 12345 00001 L
  • Perl:管理 Windows 上的路径编码

    我正在努力处理包含非英文字符的路径 Activestate Perl Windows XP 如何打开 写入 复制等位于包含希腊语 俄语 法语重音字符的路径中的文件 假设我要将 text txt 文件复制到的目录是 C Documents a
  • Invoke-Sqlcmd 运行脚本两次

    我遇到了一个非常奇怪的问题并且可以重复 基本上 我使用invoke sqlcmd通过使用 inputfile来调用脚本文件 但是如果脚本文件存在一些执行错误 例如插入到列不应为空的表中 则脚本文件将被执行两次 我也可以从探查器中看到这两个执
  • PowerShell 脚本,用于将超过 x 天的文件和文件夹(包括子文件夹)从一个位置移动到另一个位置

    我开发了一个 PowerShell 脚本 它运行得非常好 唯一的挑战是子文件夹中的文件没有移动到目的地 get childitem Path servername location where object LastWriteTime lt
  • 源代码是否应该以 UTF-8 格式保存

    以 UTF 8 格式保存源代码有多重要 Windows 上的 Eclipse 默认使用 CP1252 字符编码 CP1251 格式意味着可以保存非 UTF 8 字符 如果您从 Word 文档复制并粘贴注释以进行注释 我就看到过这种情况 我之
  • 如何使用PowerShell脚本远程启动/停止IIS 6.0/7.0?

    我有两台服务器服务器 A 和服务器 B 我想使用 Powershell 脚本从服务器 B 远程停止服务器 A 最简单的方法之一就是使用命令行执行PsExec http www microsoft com technet sysinterna
  • PSExec 中的会话 ID

    Psexec 无法在远程会话上为我显示记事本 GUI 因此 我尝试获取会话 ID 如下所示 c Users Amitra Downloads PSTools gt PsExec u administrator p force 135 20
  • Powershell:根据属性过滤属性

    我对 PowerShell 的自学经验有限 所以这可能是一些基本的东西 但我似乎无法正确理解 我在 Active Directory 中 需要提取电子邮件地址不以 SamAccountName 开头的用户列表 因此 如果您的登录名是 jdo
  • UTF8/UTF16 和 Base64 在编码方面有什么区别

    In c 我们可以使用下面的类来进行编码 System Text Encoding UTF8 System Text Encoding UTF16 System Text Encoding ASCII 为什么没有System Text En
  • 使用 powershell 版本 2 查询 AD

    我们有由 Windows 7 和 Windows 10 组成的混合桌面操作系统 我有一个登录脚本 该脚本从每次用户登录时运行的 powershell 脚本收集各种信息 Windows 7 powershell 仅是版本 2 这意味着我无法使
  • PowerShell 脚本 ffmpeg

    作为一名优秀的 Windows 系统管理员 我终于开始学习 PowerShell 话虽这么说 我不知道我在做什么 惊讶 惊讶 我认为远离生产环境 在家里使用 PowerShell 对我来说将是一次很好的学习经历 最近 我开始使用 FFMPE
  • 抑制数组列表添加方法管道输出

    我正在使用数组列表来构建日志项序列以供稍后记录 工作起来很不错 但是 Add 方法将当前索引发送到管道 我可以通过将其发送到 null 来解决这个问题 如下所示 strings Add junk gt null 但我想知道是否有某种机制可以
  • 如何在 PowerShell 中远程执行 ELEVATED 远程脚本

    我有两台服务器 serverA Windows 2003 服务器 serverB Windows 7的 ServerA包含一个带有批处理文件 deploy bat 的文件夹 需要从提升的 powershell 提示符执行该批处理文件 在Se
  • Powershell 中的“$”是什么?

    是什么意思 在 Powershell 中 Edit TechNet 答案 http technet microsoft com en us library hh847768 aspx同义反复 没有解释 成功 或 失败 的含义 包含上次操作的

随机推荐

  • python中的列表递归

    我刚开始学习python 有一些递归问题我似乎无法弄清楚 最烦人的是这个 我需要构建一个函数ind e L where e是一个整数并且L是一个列表 通过输入e如果它在列表中 则输出需要是它的索引 例如 ind 42 0 14 52 42
  • Perl 中美元符号后跟问号是什么意思?

    Perl 脚本中的以下内容 a apple b orange if 0 do something 什么是 意思是这里 这是上次系统操作 管道或反引号操作返回的状态 参见参考资料perlvar
  • Android Studio 模拟器中出现“EGL_BAD_MATCH”错误

    我有一个问题 那是什么 E EGL emulation tid 3912 eglSurfaceAttrib 1146 error 0x3009 EGL BAD MATCH 我应该怎么做才能解决该错误 public class Main ex
  • rust-chrono 中的 ParseError(NotEnough) 是什么意思?

    我在用着rust chrono我正在尝试解析这样的日期 extern crate chrono use chrono fn main let date str 2013 02 14 15 41 07 let date DateTime pa
  • 如何在 Flutter 上播放 Android 和 iOS 的 M3U8 格式

    我在 iOS 上找不到 M3U8 Url 播放器的任何解决方案 我尝试过这些插件 video player 无法播放 flutter simple video player 仅支持Android chewielib将用于播放m3u8文件 添
  • 为什么我能够使用我的值构造函数,即使我不导出它?

    作为实践 我在名为 Queue 的模块中实现了队列数据类型 我的数据类型也称为 Queue 这是它唯一的值构造函数 module Queue Queue enq emptyQueue where data Queue a Queue inb
  • 错误:“(vlog-2110) 非法引用网络”

    我在 SystemVerilog 中有一个简单的 FIFO 代码 我得到几个vlog 2110 illegal reference to net错误消息 我的错误消息后面是我的代码 错误信息 vlog work 工作 sv stats no
  • 如何使用 Java 8 流制作笛卡尔积?

    我有以下集合类型 Map
  • 从 ViewModel 获取 [key] 属性

    我有一个 ViewModel 其中有一个 key 属性 我想从该视图模型的实例中获取它 我的代码看起来像这样 虚构模型 class AddressViewModel Key ScaffoldColumn false public int U
  • “无法调用 DateTime 上的方法”以及其他限制

    有谁知道编译时未捕获的 LINQ to SQL 查询限制的明确列表 以及 如果可能 这些限制的解决方法 到目前为止我们的清单是 Calling methods such as Date on DateTime 没有找到解决方法 string
  • 如何在频域中旋转图像?

    我听说应该可以对 jpeg 图像进行无损旋转 这意味着您可以在频域中进行旋转 而无需 IDCT 我尝试用谷歌搜索但没有找到任何东西 有人可以对此带来一些启发吗 我所说的无损是指我不会在旋转中丢失任何附加信息 当然 这可能只有在旋转 90 度
  • TCP、HTTP 和多线程最佳点

    我试图了解我获得的性能数据以及如何确定最佳线程数 请参阅这篇文章的底部以获取我的结果 我用 Perl 编写了一个实验性多线程 Web 客户端 它下载一个页面 获取每个图像标签的源并下载图像 丢弃数据 它使用非阻塞连接 每个文件的初始超时为
  • 如何为图像数据集添加标签进行分类?

    我正在使用 Mac 操作系统上安装的 python 3 6 我有一个文本文件 用于存储图像名称和每个图像的类号 label txt img0001 jpg 1 img0002 jpg 3 img0003 jpg 5 img0004 jpg
  • .Net 的 Web 应用程序测试(WatiN 测试记录器)

    我一直在使用 WatiN 作为我当前项目的测试工具 除了测试记录器的小错误之外 我还能够使用它并与 NUnit 结合自动执行许多测试 还有其他人有使用他们可能建议的不同工具的经验吗 我之前使用过 Selenium 并将其挂接到CruiseC
  • rake 资产:预编译不起作用(rails 3.1.1)

    我正在部署到heroku 但我发现css文件没有被提供 它们也无法在heroku上找到 我读到我需要先在本地进行 rake asset precompile 但当我这样做时 我得到 C project gt bundle exec rake
  • “Maven->更新项目配置”菜单项在哪里?

    我在 Eclipse 项目中缺少 Maven 依赖项 正如中所述这个问题 我很想用找到的解决方案 但是当我在项目资源管理器中右键单击我的项目时 我找不到任何此类菜单项 如果我右键单击该项目的pom xml 我在 Maven 的菜单中看到的是
  • 使用 https 代理运行 AngularJS Protractor

    尝试运行量角器时 我在命令行中收到以下错误 gt 致命错误 量角器退出 代码 1 我需要代理到 https 测试服务器 我该如何实现这个目标 我听从了这个建议Github问题 但我仍然收到上述错误 这是我的配置文件 A reference
  • 如何使用 Allocations 将数组值传入和传出 Android RenderScript

    我最近一直在使用 RenderScript 目的是创建一个程序员可以轻松使用的 API 类似于 Microsoft Accelerator 的工作方式 我目前遇到的麻烦是 我想在 RenderScript 层之间传递值 并让所有内容以尽可能
  • 如何从 iPhone 视频录制中实时捕捉逐帧图像

    我正在尝试实时测量所选颜色的饱和度 如下所示 我正在关注本指南来自苹果 我更新了代码以使用 ARC 当然还使我的视图控制器成为AVCaptureVideoDataOutputSampleBufferDelegate 但我不知道如何实际开始捕
  • 如何在没有 BOM 的情况下重定向 PowerShell 中的输入?

    我正在尝试通过以下方式重定向 PowerShell 中的输入 Get Content input txt my program args 问题是管道 UTF 8 文本前面带有 BOM 0xEFBBBF 而我的程序无法正确处理它 一个最小的工