Есть ли способ указать цвет шрифта при использовании записи-вывода - PullRequest
16 голосов
/ 10 января 2011

У меня есть сценарий powershell, который дает вывод некоторого состояния через write-output .Я намеренно не использую write-host , потому что вывод может быть захвачен и записан в файл журнала следующим образом:

./myscript.ps1 | out-file log.txt

Но если вывод не перенаправлен, было бы хорошо иметьцветной вывод на консоль, потому что скрипт выдает много разных сообщений о состоянии.Я знаю, что цветной вывод возможен с write-host , но сообщения о состоянии должны быть конвейерными.

Есть идеи, как решить эту проблему?

Ответы [ 5 ]

10 голосов
/ 10 января 2011

Я пробовал эту дополнительную функцию, и она в основном работает нормально:

function Write-ColorOutput($ForegroundColor)
{
    # save the current color
    $fc = $host.UI.RawUI.ForegroundColor

    # set the new color
    $host.UI.RawUI.ForegroundColor = $ForegroundColor

    # output
    if ($args) {
        Write-Output $args
    }
    else {
        $input | Write-Output
    }

    # restore the original color
    $host.UI.RawUI.ForegroundColor = $fc
}

# test
Write-ColorOutput red (ls)
Write-ColorOutput green (ls)
ls | Write-ColorOutput yellow

Результат этого конкретного теста немного забавен: мы действительно получаем строки красного, зеленого и желтого цветов, но заголовок таблицы - красного, то есть цвет первого вызова функции.

7 голосов
/ 10 января 2011

Отделите результаты в конвейере от сообщений о состоянии в консоли.

Например, используйте такую ​​функцию в вашем скрипте:

function write-status( $status ){
   $status | write-host -fore green -back red;  #send a status msg to the console
   $status | write-output; #send a status object down the pipe
}

Я бы также рекомендовал использовать один из следующих командлетов над write-host для вывода сообщений о состоянии из ваших сценариев:

  • запись-отладка
  • ошибка записи
  • запись-подробный
  • запись предупреждения

Внешний вид этих сообщений о состоянии будет зависеть от используемого командлета. Кроме того, пользователь может отключить определенные уровни состояния с помощью переменных предпочтения $ (warning | error | verbose | debug) или перехватить определенные сообщения о состоянии с помощью общих параметров командлета переменной - (warning | error | verbose | debug).

1 голос
/ 20 февраля 2019

Таким образом:

function Green
{
    process { Write-Host $_ -ForegroundColor Green }
}

function Red
{
    process { Write-Host $_ -ForegroundColor Red }
}

Write-Output "this is a test" | Green
Write-Output "this is a test" | Red

enter image description here

1 голос
/ 24 мая 2018

У меня была такая же проблема, поэтому я поделюсь своим решением, которое, я думаю, работает довольно хорошо:

Write-ColorOutput "Hello" Green Black -NoNewLine
Write-ColorOutput " World" Red

Это командлет для его использования

function Write-ColorOutput
{
    [CmdletBinding()]
    Param(
         [Parameter(Mandatory=$False,Position=1,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][Object] $Object,
         [Parameter(Mandatory=$False,Position=2,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][ConsoleColor] $ForegroundColor,
         [Parameter(Mandatory=$False,Position=3,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][ConsoleColor] $BackgroundColor,
         [Switch]$NoNewline
    )    

    # Save previous colors
    $previousForegroundColor = $host.UI.RawUI.ForegroundColor
    $previousBackgroundColor = $host.UI.RawUI.BackgroundColor

    # Set BackgroundColor if available
    if($BackgroundColor -ne $null)
    { 
       $host.UI.RawUI.BackgroundColor = $BackgroundColor
    }

    # Set $ForegroundColor if available
    if($ForegroundColor -ne $null)
    {
        $host.UI.RawUI.ForegroundColor = $ForegroundColor
    }

    # Always write (if we want just a NewLine)
    if($Object -eq $null)
    {
        $Object = ""
    }

    if($NoNewline)
    {
        [Console]::Write($Object)
    }
    else
    {
        Write-Output $Object
    }

    # Restore previous colors
    $host.UI.RawUI.ForegroundColor = $previousForegroundColor
    $host.UI.RawUI.BackgroundColor = $previousBackgroundColor
}
0 голосов
/ 23 июня 2017

Я знаю, что этот пост древний, но это может пригодиться кому-то там.

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

EDIT:

# Print User message using String Array $message
function PrintMessageToUser {
    param(
        [Parameter( `
            Mandatory=$True, `
            Valuefrompipeline = $true)]
        [String]$message
    )
    begin {
        $window_private_data = (Get-Host).PrivateData;
        # saving the original colors
        $saved_background_color = $window_private_data.VerboseBackgroundColor
        $saved_foreground_color = $window_private_data.VerboseForegroundColor
        # setting the new colors
        $window_private_data.VerboseBackgroundColor = 'Black';
        $window_private_data.VerboseForegroundColor = 'Red';
    }
    process {
        foreach ($Message in $Message) {
            # Write-Host Considered Harmful - see http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/
            # first way how to correctly write it
            #Write-host $message;
            Write-Verbose -Message $message -Verbose;
            # second correct way how to write it
            #$VerbosePreference = "Continue"
            #Write-Verbose $Message;
        }
    }
    end {
      $window_private_data.VerboseBackgroundColor = $saved_background_color;
      $window_private_data.VerboseForegroundColor = $saved_foreground_color;
    }

} # end PrintMessageToUser
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...