Linux 将文本管道化到外部程序会附加一个尾随换行符
我一直在比较多个系统之间的散列值,惊讶地发现PowerShells散列值与其他终端的散列值不同 Linux终端(CygWin、Bash for Windows等)和Windows命令提示符都显示相同的哈希值,而as PowerShell则显示不同的哈希值 这是使用SHA256测试的,但在使用其他算法(如md5)时发现了相同的问题 编码更新: 尝试更改PShell编码,但对返回的哈希值没有任何影响Linux 将文本管道化到外部程序会附加一个尾随换行符,linux,powershell,hash,pipe,newline,Linux,Powershell,Hash,Pipe,Newline,我一直在比较多个系统之间的散列值,惊讶地发现PowerShells散列值与其他终端的散列值不同 Linux终端(CygWin、Bash for Windows等)和Windows命令提示符都显示相同的哈希值,而as PowerShell则显示不同的哈希值 这是使用SHA256测试的,但在使用其他算法(如md5)时发现了相同的问题 编码更新: 尝试更改PShell编码,但对返回的哈希值没有任何影响 [Console]::OutputEncoding.BodyName iso-8859-1 [C
[Console]::OutputEncoding.BodyName
iso-8859-1
[Console]::OutputEncoding = [Text.UTF8Encoding]::UTF8
utf-8
GitHub PowerShell问题
Linux终端和PowerShell使用不同的编码。因此,
echo-n“string”
产生的实际字节是不同的。我在我的LinuxMint终端和Windows10PowerShell上试用了它。这是我得到的:
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将换行符\r\n
(0D 00 0A 00
)放在“字符串”的末尾
编辑:如下所述,Windows PowerShell在管道传输时默认使用ASCII。tl;医生: PowerShell使用存储在中的编码对发送到外部程序的字符串进行编码,并始终附加一个尾随(适用于平台)换行符 因此,关键是避免PowerShell的管道,以利于本机shell,从而防止隐式添加尾随换行符:
- 如果您正在类Unix平台(使用PowerShell Core)上运行命令:
printf%s
是echo-n
的便携式替代品。如果字符串包含'
字符,请将其加倍或使用`“…`”
引号
- 如果您需要在Windows上通过
执行此操作,事情会变得更加棘手,因为cmd.exe
不直接支持没有尾随换行符的回显:cmd.exe
cmd/c“您知道,在PowerShell中,echo-n
实际上是写入输出-NoEnumerate
,因为别名,对吧?可能是、、等的重复。尝试将编码更改为UTF-8,但它不会更改哈希结果。我不是PowerShell人员,但是,对于一个有Unix/Linux背景的人来说,我所看到的关于它的一切都是可怕的,他希望它像shell脚本一样工作。一旦我看到我必须为一个简单的grep
和sed
做些什么,我就放弃了PowerShell。至少在默认情况下,PowerShell在连接到外部程序时不使用UTF-16LE。自动$outpuneCoding
变量确定管道传输到外部程序(如openssl
)时使用的编码,Windows PowerShell中默认为ASCII,PowerShell Core中默认为UTF-8。确实是不断添加的尾随新行导致了这里的问题;在PowerShell中,您可以将-n
与echo
一起使用,但其语义不同(echo-n
相当于Write Output-NoEnumerate
)。@jwww:PowerShell从历史上讲,习惯于作为自己的世界;随着它向跨平台的过渡,在与外部实用程序交互时,它还有一些东西需要学习,而外部实用程序在Unix世界比在Windows世界更重要。我鼓励你在@Pie:Thank上帮助这个过程;总而言之:真正的问题是,当管道连接到外部程序时,PowerShell管道本身附加了一个尾随的换行符;这不是编码问题(可能在Windows PowerShell中使用包含非ASCII字符的字符串时除外)。因为这个答案侧重于编码(并且歪曲了代码转换如何与外部程序一起工作),所以我的答案是a-1。
sh -c "printf %s 'string' | openssl dgst -sha256 -hmac authcode"
cmd /c "<NUL set /p =`"string`"| openssl dgst -sha256 -hmac authcode"