Запись в поток ошибок в Powershell с использованием Write-Error

Почему не Пауэршелл Write-Error командлет у меня работает? Мой вывод не похож на примеры в документации:

PS C:\> Write-Error "This is an error"
Write-Error "This is an error" : This is an error
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

Я ожидал выхода, похожего на Write-Warning:

PS H:\> Write-Warning "This is a warning"
WARNING: This is a warning

От Write-Error а также about_preference_variables документация, я думал, я не должен видеть никаких исключений?

PS H:\> Get-Help About_Preference_Variables

$ErrorActionPreference
----------------------

...

        PS> $erroractionpreference                      
        Continue        # Display the value of the preference.                

        PS> write-error "Hello, World"                  
                                # Generate a non-terminating error.

        write-error "Hello, World" : Hello, World       
                                # The error message is displayed and
                                  execution continues.

        PS> write-error "Hello, World" -ErrorAction:SilentlyContinue
                                # Use the ErrorAction parameter with a 
                                  value of "SilentlyContinue".
        PS>                                             
                                # The error message is not displayed and
                                  execution continues.

4 ответа

Решение

Чтобы получить вывод, похожий на запись-предупреждение, вы можете сделать это:

$Host.UI.WriteErrorLine("This is an error")

(поддерживает Криса Сирса за этот ответ)

Почему ты не думаешь, что это работает? Имейте в виду, что PowerShell различает не прекращающиеся ошибки, подобные предыдущей, и завершающие ошибки, которые вы получаете при выполнении throw 'Access denied.', Не завершающие ошибки записываются в stderr и регистрируются в коллекции ошибок $, но они не останавливают обработку скрипта. Эта функция очень удобна, когда вы обрабатываете (например, удаляете или копируете) кучу файлов. Вы хотите знать, какие файлы не могут быть обработаны, но вы не хотите, чтобы вся операция остановилась на первом файле с ошибкой.

PowerShell также дает вам возможность "преобразовывать" не прекращающиеся ошибки в завершающие ошибки, например

Remove-Item c:\file-doesnt-exist -ErrorAction Stop; "Did I get here"

Обратите внимание, что в этом случае выполнение останавливается и не выводит строку в конце. Попробуй без -ErrorAction Stop и вы увидите ошибку, но вы также увидите строку "Я сюда попал".

Если вы хотите контролировать информацию о Catogory, вы можете использовать параметр -Category следующим образом:

PS> write-error "foo" -Category 'InvalidResult'
write-error "foo" -Category 'InvalidResult' : foo
    + CategoryInfo          : InvalidResult: (:) [Write-Error], WriteErrorExce..
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

Но WriteErrorException - это механизм (я думаю), с помощью которого этот командлет вызывает ошибку. Есть Exception параметр, но мне не повезло, используя его.

Проблема здесь в том, что мы предположили шаблон для вывода подробных информационных сообщений, предупреждений и сообщений об ошибках и ожидаем, что Write-командлеты, чтобы сформировать набор, соответствующий этому шаблону.

Но Write-Errorотличается и ставит под сомнение, был ли такой шаблон задуман авторами или просто был в уме программиста. Это газлайтинг дизайна API.

Write-Verbose

Командлет Write-Verbose записывает текст в поток подробных сообщений в PowerShell.

Предупреждение о записи

Командлет Write-Warning записывает предупреждающее сообщение на узел PowerShell.

Ошибка записи

Командлет Write-Error объявляет неустранимую ошибку.

Ой. Он делает что-то другое. Он "объявляет" ошибку. Это как поднять событие. Он не пишет текст в стандартную ошибку....

Я полагаю, вы видите ожидаемый результат от этого командлета. Вы вводите "Доступ запрещен". аргумент, и он выводит это на хост и, скорее всего, на поток ошибок, как и планировалось. Вы можете подтвердить, что он выводится в переменную $Error, и он должен быть заполнен только что вставленной ошибкой.

т.е.

PS C:\> $error.Clear()

PS C:\> Write-Error "access denied"

Write-Error "access denied" : access denied

    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

PS C:\> $error

Write-Error "access denied" : access denied

    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

Я могу видеть, где это может сбить с толку, хотя, возможно, MSFT должен изменить пример ошибки с что-то вроде "Отказано в доступе" на "Foobar" для ясности.

Отредактируйте, чтобы ответить на следующий вопрос: Действие errorAction по умолчанию для Write-Error - это "продолжить", поэтому, чтобы заставить его вести себя как Write-Warning, вам нужно добавить -ErrorAction SilentlyContinue. Рассмотрим следующий пример:

PS E:\> $error.clear()
PS E:\> Write-Error 'test'
Write-Error 'test' : test
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

PS E:\> Write-Error 'test2' -ErrorAction silentlycontinue  

PS E:\> $error[1]
Write-Error 'test' : test
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

PS E:\> $error[0]
Write-Error 'test2' -ErrorAction silentlycontinue : test2
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
Другие вопросы по тегам