将文本传输到外部程序会附加尾随换行符

2024-10-30 08:35:00
admin
原创
186
摘要:问题描述:我一直在比较多个系统之间的哈希值,惊讶地发现 PowerShell 的哈希值与其他终端的哈希值不同。Linux 终端(CygWin、Windows 的 Bash 等)和 Windows 命令提示符都显示相同的哈希值,而 PowerShell 显示不同的哈希值。使用 SHA256 进行了测试,但在使用...

问题描述:

我一直在比较多个系统之间的哈希值,惊讶地发现 PowerShell 的哈希值与其他终端的哈希值不同。

Linux 终端(CygWin、Windows 的 Bash 等)和 Windows 命令提示符都显示相同的哈希值,而 PowerShell 显示不同的哈希值。

Linux 与 PShell 哈希比较

使用 SHA256 进行了测试,但在使用 md5 等其他算法时发现同样的问题。

编码更新:

尝试更改 PShell 编码,但对返回的哈希值没有任何影响。

[Console]::OutputEncoding.BodyName 
iso-8859-1
[Console]::OutputEncoding = [Text.UTF8Encoding]::UTF8
utf-8

GitHub PowerShell 问题

https://github.com/PowerShell/PowerShell/issues/5974


解决方案 1:

更新

PowerShell(核心) v7.4+现在支持使用外部程序处理原始字节(参见此答案),从而实现以下更简单的解决方案:

  • 在类Unix平台上:

# PS v7.4+ only, on Unix-like platforms
# No newline will be appended; the raw byte output from external program printf
# is passed through.
printf %s 'string' | openssl dgst -sha256 -hmac authcode
  • Windows上(也适用于 Unix):

# PS v7.4+ only, on any supported platform.
# Send the *byte* representation of the string to external program openssl.
# If you were to send the string directly, PowerShell would append a newline.
, [Text.Encoding]::UTF8.GetBytes('string') | openssl dgst -sha256 -hmac authcode

因此,以下内容仅适用于Windows PowerShellPowerShell (Core) v7.3-


总结:

当 PowerShell 通过管道将字符串传输到外部程序时:

  • 它使用存储在偏好变量中的字符编码对其进行编码$OutputEncoding

  • 总是附加一个尾随的(适合平台的)换行符

因此,关键是避免使用PowerShell 的管道而使用本机 shell 的管道,以防止隐式添加尾随换行符

  • 如果您在类Unix平台上运行命令(使用 PowerShell Core):

sh -c "printf %s 'string' | openssl dgst -sha256 -hmac authcode"

printf %s是 的可移植替代方案echo -n。如果字符串包含'字符,请将其加倍或使用`"..."`引号。

  • 如果您需要在Windows上通过cmd.exe执行此操作,事情会变得更加棘手,因为cmd.exe它不直接支持不带尾随换行符的回显:

cmd /c "<NUL set /p =`"string`"| openssl dgst -sha256 -hmac authcode"

请注意,此方法之前不能有空格。有关此解决方案的说明和限制,请参阅 此答案。|

仅当字符串包含非 ASCII 字符并且您在Windows PowerShell 中运行时,才会出现编码问题;在这种情况下,首先设置$OutputEncoding为目标实用程序所需的编码,通常为 UTF-8:$OutputEncoding = [Text.Utf8Encoding]::new()


  • 当您通过管道将没有换行符的字符串发送到外部实用程序时, PowerShell总会附加一个尾随换行符,这就是您观察到的差异的原因(尾随换行符在 Unix 平台上仅为 LF,在 Windows 上为 CRLF 序列)。

+ 您可以在 OP 打开的GitHub 问题 #5974中跟踪解决此问题的努力。
  • 此外,在 Windows PowerShell 和 PowerShell (Core) 中,直到 v7.3.x 版本,在将数据传输到外部程序时,PowerShell 的管道始终是基于文本的;内部基于 UTF-16LE 的 PowerShell (.NET) 字符串根据存储在自动变量中的编码进行转码,在Windows$OutputEncoding PowerShell中默认为仅 ASCII 编码,在 PowerShell Core中默认为 UTF-8 编码(在 Windows 和类 Unix 平台上)。

+ ***PowerShell(核心)v7.4+*现在*支持*使用外部程序进行原始字节处理**- 请参阅此答案。
  • 因此,echo -nPowerShell 中不会产生没有尾随换行符的字符串这一事实与您的问题无关;为了完整起见,这里有一个解释:

+ `echo`是 PowerShell cmdlet 的别名,在管道传输到*外部*程序`Write-Output`的上下文中,它将*文本写入下**一个*管道段中的程序标准输入(类似于 Bash/cmd.exe )。`echo`
+ `-n``Write-Output`被解释为开关的(明确的)缩写`-NoEnumerate`。
+ `-NoEnumerate`仅适用于写入*多个*对象时,因此这里没有效果。
+ 因此,简而言之:在 PowerShell 中,`echo -n "string"`与 相同`Write-Output -NoEnumerate "string"`,因为只输出一个字符串 - 与 相同`Write-Output "string"`,而这反过来又与仅使用 相同`"string"`,依赖于 PowerShell 的*隐式*输出行为。
+ `Write-Output`没有选项可以抑制尾随换行符,即使有,使用管道传输到*外部*程序也会将其添加回来。

解决方案 2:

Linux 终端和 PowerShell 使用不同的编码。因此产生的实际字节echo -n "string"不同。我在 Linux Mint 终端和 Windows 10 PowerShell 上尝试了此操作。以下是我得到的结果:

Linux Mint:

73 74 72 69 6E 67

Windows 10:

FF FE 73 00 74 00 72 00 69 00 6E 00 67 00 0D 00 0A 00

似乎 Linux 终端使用 UTF-8,而 Windows PowerShell 使用带 BOM 的 UTF-16。此外,在 PowerShell 中,您不能为 echo 使用“-n”参数。因此 echo 将换行符`
( 0D 00 0A 00`) 放在“字符串”末尾。

编辑:正如mklement0下面所说,Windows PowerShell 在管道传输时默认使用 ASCII。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用