从cmd.exe的命令捕捉输出缺少最终换行符

问题描述 投票:1回答:2

我想打电话给一个像cmd在PowerShell中使用内置echo命令Invoke-Expression并将其转换为一个字节数组,但换行是从命令的输出丢失。

例:

([Text.Encoding]::ASCII).GetBytes((iex "cmd /c echo."))

它没有返回值,而不是一个新行序列(CRLF)。

windows powershell cmd command-line command
2个回答
0
投票

TL;博士:

PS> ([text.encoding]::ASCII).GetBytes(((cmd /c echo.) -join "`r`n") + "`r`n")
13
10

顺便说一句:iex (Invoke-Expression) should be avoided

请继续阅读,背景信息和注意事项。


当PowerShell的捕获来自外部程序的stdout输出诸如cmd.exe,它返回的输出线的阵列,从每个修整后换行序列。

顺便说一句:这是[console]::OutputEncoding报道的字符编码,确定PowerShell如何解释输出,Windows PowerShell中默认为遗留系统语言环境的OEM代码页,并且,截至记者发稿,也 - 仍然-in PowerShell核心Windows上,尽管这will hopefully change soon,鉴于PowerShell核心否则用途(BOM-更少)UTF-8作为默认编码。

在你的情况,cmd /c echo.发出一个单一的Windows行序列,CRLF,其中,在PowerShell中的术语,是"`r`n"(你也可以使用[Environment]::NewLine获得一个平台,适当换行字符串)。

PowerShell的解释,作为一个单一的空行,而且,由于不包括在数组元素结尾的换行和PowerShell展开一单元素数组,你最终'',即空字符串 - 这就是为什么([text.encoding]::ASCII).GetBytes()呼叫产生没有输出。

可以重新组装该创建的powershell成一个单一的,多线输出串由输出线阵列:

  • 用换行接合数组元素(-join "`r`n"
  • 附加的最终拖尾换行符(+ "`r`n"

如上所示。

注意事项:此“重组”提出了两个假设可能并不总是正确的:

  • 外置程序真的发出的Windows CRLF序列,而不是UNIX LF-只字符。 然而在实践中,这种差异很少在PowerShell中的问题,因为它同时接受换行符形式互换。
  • 外置程序确实发出一个尾随换行符 - 这是典型的,但不一定是真实的。

如果这些假设是有问题的,输出重定向到一个文件并读取 - 为your own answer - 是正确的解决方案。

警告:> Windows PowerShell中默认创建UTF-16LE文件(也总是附加一个新行),这样你就不会得到ASCII字节;因此,使用cmd自身重定向以产生文件(将使用由chcp指示的遗留OEM编码,这通常是ASCII的超集):

  # Note that the `>` is *inside the quoted string* to ensure that it is
  # cmd.exe that interprets it.
  # (...) around `echo.` ensures that the space before `>` doesn't become
  # part of the output.
  PS> cmd /c '(echo.) >out.txt'; [IO.File]::ReadAllBytes("$PWD\out.txt")
  13
  10

0
投票

我找到了解决办法。并不完美,但我会写输出到文件,与[System.IO.File]::ReadAllBytes("path_to_the_file")阅读并保存到变量

© www.soinside.com 2019 - 2024. All rights reserved.