Как перехватить сообщения об ошибках, выданные командой?

powershell

46054 просмотра

3 ответа

Я пишу сценарий PowerShell, в котором мне нужно захватить сообщение об ошибке, которое он выдает. Примечание: согласно PowerShell, ошибки нет, и команда выполнена успешно.

Например: я пытался скачать пакет из SVN Link. Ссылка на самом деле нет. Скрипт показывает мне сообщение об ошибке на консоли. Однако, когда я попытался проверить $_или $?или $error, я не увидел ни одного сообщения об ошибке. Тем не менее, $LASTEXITCODEвозвращается значение 1. Мне нужно получить точное сообщение об ошибке.

Автор: Avinash Ganesh Источник Размещён: 12.11.2019 09:25

Ответы (3)


26 плюса

Решение

Если вы получаете сообщение об ошибке, вам нужно перехватить поток ошибок:

$msg = command 2>&1

или же

command 2>error.txt

PowerShell записывает свои сообщения в разные потоки, которые можно перенаправить в файлы для захвата соответствующего вывода.

  • Поток 1 (по умолчанию): обычный вывод («STDOUT»)
  • Поток 2: сообщения об ошибках («STDERR»), включая сообщения об ошибках от внешних программ
  • Поток 3: предупреждающие сообщения
  • Поток 4: подробные сообщения
  • Поток 5: отладочные сообщения
  • Поток 6: информационные сообщения (только PowerShell v5 и новее)

Чтобы захватить определенный поток в файле, вам нужно перенаправить номер потока на имя файла. Например

command 2>"C:\path\to\error.log"

будет захватывать все сообщения об ошибках, созданные commandв файле C:\path\to\error.log. Используйте 2>>вместо того 2>, чтобы добавить файл в файл, а не перезаписывать его при каждом запуске.

Вы также можете объединить другие потоки с STDOUT для обработки / перенаправления всей команды:

command >>"C:\path\to\all.log" *>&1

Смотрите Get-Help about_Redirectionили эту статью Scripting Guy для получения дополнительной информации о потоках и перенаправлении.

Вещи стоит отметить:

  • *>Перенаправление было введено с PowerShell v3, поэтому он не будет работать в PowerShell v2 и ранее.
  • В PowerShell v5 появился новый поток ( Информация , поток № 6), поскольку люди продолжали злоупотреблять, Write-Hostпотому что не понимали, для чего предназначен командлет.
Автор: Ansgar Wiechers Размещён: 02.07.2013 08:47

5 плюса

Предполагая, что ваш исполняемый файл называется svn.exe и находится в пути, вы можете перехватить сообщения, которые он отправляет на консоль, следующим образом:

$msg = [string] (svn.exe <your parameters here>)

Затем вы можете проанализировать строку $ msg, чтобы найти нужную вам информацию.

Автор: David Brabant Размещён: 02.07.2013 08:17

2 плюса

Вдохновленный ответом Дэвида Брабантса , вы можете объединить stdout и stderr в один строковый массив с помощью этой команды:

$output = [string[]] (.\Cli.exe -p $param 2>&1)

Он будет выполняться Cli.exeс параметром p. Это опционально.

осветление

2>&1означает, что поток # 2 ( stderr ) будет перенаправлен на поток # 1 ( stdout ), таким образом оба потока будут поступать в $output.

Автор: Bruno Zell Размещён: 30.01.2018 02:46
Вопросы из категории :
32x32