[英]Captured output from a cmd.exe command is missing a final newline
I'm trying to call a built-in cmd
command like echo
in PowerShell using Invoke-Expression
and convert it to a byte array, but the newlines are missing from the command output. 我正在尝试使用
Invoke-Expression
在PowerShell中Invoke-Expression
诸如echo
的内置cmd
命令并将其转换为字节数组,但是命令输出中缺少换行符。
Example: 例:
([Text.Encoding]::ASCII).GetBytes((iex "cmd /c echo."))
It returns nothing instead of a newline sequence (CRLF). 它不返回任何内容,而不是换行序列(CRLF)。
I found a solution. 我找到了解决方案。 Not perfect but i will write output to file, read it with
[System.IO.File]::ReadAllBytes("path_to_the_file")
and save to variable 并不完美,但是我将输出写入文件,使用
[System.IO.File]::ReadAllBytes("path_to_the_file")
读取并保存到变量
tl;dr: tl; dr:
PS> ([text.encoding]::ASCII).GetBytes(((cmd /c echo.) -join "`r`n") + "`r`n")
13
10
As an aside: iex
( Invoke-Expression
) should be avoided . iex
: 应该避免使用iex
( Invoke-Expression
) 。
Read on for background information and caveats. 请继续阅读以获取背景信息和注意事项。
When PowerShell captures stdout output from an external program such as cmd.exe
, it returns an array of output lines , with the trailing newline sequence trimmed from each. 当PowerShell捕获来自外部程序(例如
cmd.exe
stdout输出时 ,它将返回输出行 数组 ,并从每个输出行中修剪尾随的换行符序列。
As an aside: It is the character encoding reported by [console]::OutputEncoding
that determines how PowerShell interprets the output, which in Windows PowerShell defaults to the legacy system locale's OEM code page, and, as of this writing, also - still -in PowerShell Core on Windows , though that will hopefully change soon , given that PowerShell Core otherwise uses (BOM-less) UTF-8 as the default encoding. [console]::OutputEncoding
说[console]::OutputEncoding
: [console]::OutputEncoding
报告的字符编码确定PowerShell如何解释输出,在Windows PowerShell中默认为旧系统语言环境的OEM代码页,并且在撰写本文时,仍然-在Windows上的 PowerShell Core 中 ,尽管希望 PowerShell 很快改变 ,因为PowerShell Core否则将使用(无BOM)UTF-8作为默认编码。
In your case, cmd /c echo.
在您的情况下,
cmd /c echo.
emitted a single Windows newline sequence, CRLF, which, in PowerShell terms, is "`r`n"
(you can also use [Environment]::NewLine
to obtain a platform-appropriate newline string). 发出了单个Windows换行符序列CRLF,以PowerShell术语来说,它是
"`r`n"
(您也可以使用[Environment]::NewLine
获得适合于平台的换行符)。
PowerShell interprets that as a single empty line, and, due to not including the trailing newline in the array elements and PowerShell unwrapping a single-element array, you end up with ''
, ie, the empty string - this is why the ([text.encoding]::ASCII).GetBytes()
call produced no output. PowerShell会将其解释为一个空行,并且由于不将尾随换行符包含在数组元素中,并且PowerShell展开了一个单元素数组,因此您最终得到了
''
,即空字符串 -这就是([text.encoding]::ASCII).GetBytes()
调用未产生任何输出。
You can reassemble the output-lines array that PowerShell created into a single, multi-line output string by: 您可以通过以下方法将 PowerShell创建的输出行数组重组为一个多行输出字符串:
-join "`r`n"
) -join "`r`n"
) + "`r`n"
) + "`r`n"
) as shown above. 如上图所示。
Caveats : This "reassembly" makes two assumptions that may not always be true: 注意事项 :这种“重组”有两个可能并不总是正确的假设 :
That the external program really emitted Windows CRLF sequences and not UNIX LF-only characters. 外部程序确实发出了Windows CRLF序列,而不是仅UNIX LF字符。
That the external program really emitted a trailing newline - which is typically, but not necessarily true. 外部程序确实发出了尾随换行符-通常,但不一定如此。
If these assumptions are problematic, redirecting the output to a file and reading that - as in your own answer - is the right solution. 如果这些假设有问题,那么将输出重定向到文件并按照您自己的答案 读取该 文件是正确的解决方案。
Caveat : >
in Windows PowerShell creates UTF-16LE files by default (and also invariably appends a newline), so you won't get ASCII bytes; 警告 :
>
在Windows PowerShell中默认创建UTF-16LE文件(也总是附加一个新行),这样你就不会得到ASCII字节; therefore, use cmd
's own redirection to produce the file (which will use the legacy OEM encoding indicated by chcp
, which is typically a superset of 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.