tl; др:
PS> ([text.encoding]::ASCII).GetBytes(((cmd /c echo.) -join "`r`n") + "`r`n")
13
10
В качестве отступления: iex
(Invoke-Expression
) следует избегать .
Для получения справочной информации и предупреждений читайте далее.
Когда PowerShell захватывает вывод stdout из внешней программы , такой как cmd.exe
, он возвращает массив выходных данных строк , с завершающей последовательностью новой строки , обрезанной от каждого.
В качестве отступления: Это кодировка , сообщаемая [console]::OutputEncoding
, определяющая, как PowerShell интерпретирует выходные данные, которые в Windows PowerShell по умолчанию соответствуют кодовой странице OEM старой языковой системы, а на момент написания этой статьи также - все еще -в PowerShell Core в Windows , хотя , как мы надеемся, скоро изменится , учитывая, что PowerShell Core в противном случае использует (без спецификации) 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, потому что он принимает боth символ новой строки взаимозаменяемо .
что внешняя программа действительно испустила трейлинг символ новой строки - что обычно, но не обязательно верно.
Если эти предположения проблематичны, перенаправляет вывод в файл и , читая , что - как в ваш собственный ответ - правильное решение.
Предупреждение : >
в Windows PowerShell создает файлы UTF-16LE по умолчанию (а также неизменно добавляет символ новой строки),поэтому вы не получите ASCII байтов;поэтому используйте перенаправление cmd
* own для создания файла (который будет использовать устаревшую OEM-кодировку, обозначенную chcp
, которая обычно является superset 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