【发布时间】:2017-01-10 19:07:12
【问题描述】:
关于如何使用 powershell 为我在 Jenkins 上的输出着色有什么想法吗?我已经在我的 Jenkins 上安装了 AnsiColor 插件,并且我已经将作业设置为使用 AnsiColor。唯一的问题是如何让我的powershell在Jenkins上输出颜色。
【问题讨论】:
标签: powershell jenkins jenkins-plugins ansi-colors
关于如何使用 powershell 为我在 Jenkins 上的输出着色有什么想法吗?我已经在我的 Jenkins 上安装了 AnsiColor 插件,并且我已经将作业设置为使用 AnsiColor。唯一的问题是如何让我的powershell在Jenkins上输出颜色。
【问题讨论】:
标签: powershell jenkins jenkins-plugins ansi-colors
使用ANSI escape codes 渲染颜色的插入式Write-Host 替换。 允许在 CI 系统中进行彩色输出。
.Synopsis
Write-Host but with ANSI colors!
.Description
Drop-in Write-Host replacement that uses ANSI escape codes to render colors.
Allows for colorized output in CI systems.
.Parameter Object
Objects to display in the host.
.Parameter ForegroundColor
Specifies the text color. There is no default.
.Parameter BackgroundColor
Specifies the background color. There is no default.
.Parameter Separator
Specifies a separator string to insert between objects displayed by the host.
.Parameter NoNewline
The string representations of the input objects are concatenated to form the output.
No spaces or newlines are inserted between the output strings.
No newline is added after the last output string.
.Example
Write-Host 'Double rainbow!' -ForegroundColor Magenta -BackgroundColor Yellow
.Notes
Author : beatcracker (https://github.com/beatcracker)
License: MS-PL (https://opensource.org/licenses/MS-PL)
Source : https://github.com/beatcracker/Powershell-Misc
#>
function Write-Host {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline)]
[Alias('Msg', 'Message')]
[System.Object[]]$Object,
[System.Object]$Separator,
[System.ConsoleColor]$ForegroundColor,
[System.ConsoleColor]$BackgroundColor,
[switch]$NoNewline
)
Begin {
# Map ConsoleColor enum values to ANSI colors
# https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit
$AnsiColor = @(
30, 34, 32, 36, 31, 35, 33, 37, 90, 94, 92, 96, 91, 95, 93, 97
)
# PS < 6.0 doesn't have `e escape character
$Esc = [char]27
$AnsiTemplate = "$Esc[{0}m{1}$Esc[{2}m"
}
Process {
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters#escape-e
# https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/wmf/whats-new/console-improvements#vt100-support
if ($Host.UI.SupportsVirtualTerminal) {
$Method = if ($NoNewline) { 'Write' } else { 'WriteLine' }
$Output = if ($Separator) { $Object -join $Separator } else { "$Object" }
# Splitting by regex ensures that this will work on files from Windows/Linux/macOS
# Get-Content .\Foobar.txt -Raw | Write-Host -ForegroundColor Red
foreach ($item in $Output -split '\r\n|\r|\n') {
if ("$BackgroundColor") {
$item = $AnsiTemplate -f ($AnsiColor[$BackgroundColor.value__] + 10), $item, 49
}
if ("$ForegroundColor") {
$item = $AnsiTemplate -f $AnsiColor[$ForegroundColor.value__], $item, 39
}
[System.Console]::$Method($item)
}
}
else {
Microsoft.PowerShell.Utility\Write-Host @PSBoundParameters
}
}
}
【讨论】:
我在 Jenkins 中使用了很多长的 powershell,颜色是必不可少的! 我在我的 Jenkins 用户的 profile.ps1 中覆盖了本机 Write-Host。现在我所有的本地脚本都在 Jenkins 上着色了
function Write-Host {
<#
.SYNOPSIS
Wrapper for Write-Host, adds ANSI SGR codes based on -foregroundColor and -backgroundColor
.DESCRIPTION
Renplace le Write-host standard, pour une compatibilité avec les sorties linux (JENKINS)
.PARAMETER object
Liste de String qui seront regroupe et affichée en couleur
.PARAMETER foregroundColor
Couleur du texte
.PARAMETER backgroundColor
Couleur de fond
.PARAMETER nonewline
si pas de retour a la ligne
.NOTES
? Alban LOPEZ 2018
? alban.lopez@gmail.com
? http://git/PowerTech/
#>
param(
$object,
[ConsoleColor]$foregroundColor,
[ConsoleColor]$backgroundColor,
[switch]$nonewline
)
if (!(Get-Command Write-HostOriginal -ea 0).name){ # doit etre embarque (pour les scriptblock)
$global:ConsoleOutput = ''
$metaData = New-Object System.Management.Automation.CommandMetaData (Get-Command 'Microsoft.PowerShell.Utility\Write-Host')
Invoke-Expression "function Global:Write-HostOriginal { $([System.Management.Automation.ProxyCommand]::create($metaData)) }"
}
# https://msdn.microsoft.com/en-us/library/system.consolecolor(v=vs.110).aspx
# Converted to closest ANSI SGR equivalent
$AnsiColor = [pscustomobject][ordered]@{ # doit etre embarque (pour les scriptblock)
ForeGround = [pscustomobject][ordered]@{
Black = 30
Red = 91
DarkRed = 31
Green = 92
DarkGreen = 32
Yellow = 93
DarkYellow = 33
Blue = 94
DarkBlue = 34
Magenta = 95
DarkMagenta = 35
Cyan = 96
DarkCyan = 36
White = 97
Gray = 37
DarkGray = 90
}
BackGround = [pscustomobject][ordered]@{
Black = 40
White = 107
Red = 101
DarkRed = 41
Green = 102
DarkGreen = 42
Yellow = 103
DarkYellow = 43
Blue = 104
DarkBlue = 44
Magenta = 105
DarkMagenta = 45
Cyan = 106
DarkCyan = 46
Gray = 47
DarkGray = 100
}
style = [pscustomobject][ordered]@{
RESET = 0
BOLD_ON = 1
ITALIC_ON = 3
UNDERLINE_ON = 4
BLINK_ON = 5
REVERSE_ON = 7
# BOLD_OFF = 22
# ITALIC_OFF = 23
# UDERLINE_OFF = 24
# BLINK_OFF = 25
# REVERSE_OFF = 27
}
}
function Colorize-Text {
<#
.SYNOPSIS
Adds ANSI SGR codes to a string.
.DESCRIPTION
Adds ANSI SGR codes to a string.
.PARAMETER text
Text to be transformed.
.PARAMETER ansiSgrCode
ANSI SGR number to insert.
See https://en.wikipedia.org/wiki/ANSI_escape_code for details
Or use the [AnsiColor] enum.
Also accepts an array of SGR numbers, and will apply all of them.
.NOTES
Designed to play nicely with https://wiki.jenkins-ci.org/display/JENKINS/AnsiColor+Plugin
.EXAMPLE
Colorize-Text 'toto' 7,93,101
#>
param(
$object,
[int[]]$ansiCodes #https://en.wikipedia.org/wiki/ANSI_escape_code#graphics
)
return "$([char]27)[$($ansiCodes -join(';'))m$object$([char]27)[0m"
}
$ansiCodes = @()
if($style){
$ansiCodes += $AnsiColor.style.$style
}
if($foregroundColor){
$ansiCodes += $AnsiColor.ForeGround.$foregroundColor
}
if($backgroundColor) {
$ansiCodes += $AnsiColor.BackGround.$backgroundColor
}
# Write-HostOriginal (Colorize-Text $object -ansiCodes $ansiCodes ) -nonewline # | Out-Host
# (Colorize-Text $object -ansiCodes $ansiCodes ) | Out-Host
# [Console]::Write( (Colorize-Text $object -ansiCodes $ansiCodes ) )
if($foregroundColor -and $backgroundColor){
# Write-HostOriginal (Colorize-Text $object -ansiCodes $ansiCodes ) -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor -nonewline # | Out-Host
$global:ConsoleOutput += (Colorize-Text $object -ansiCodes $ansiCodes )
} elseif($foregroundColor){
# Write-HostOriginal (Colorize-Text $object -ansiCodes $ansiCodes ) -ForegroundColor $foregroundColor -nonewline # | Out-Host
$global:ConsoleOutput += (Colorize-Text $object -ansiCodes $ansiCodes )
} elseif($backgroundColor){
# Write-HostOriginal (Colorize-Text $object -ansiCodes $ansiCodes ) -BackgroundColor $backgroundColor -nonewline # | Out-Host
$global:ConsoleOutput += (Colorize-Text $object -ansiCodes $ansiCodes )
} else {
# Write-HostOriginal $object -nonewline # | Out-Host
$global:ConsoleOutput += $object
}
if (!$nonewline) {
Write-HostOriginal $global:ConsoleOutput # -NoNewline
$global:ConsoleOutput = ''
# Write-HostOriginal '$!' -fore magenta
}
}
此代码在线程和远程使用(Start-Job,Invoke-command)中与ScriptBlock兼容
【讨论】:
Invoke-Command -ComputerName $nodeName -Authentication NegotiateWithImplicitCredential -ScriptBlock ${function:Set-WinServiceQC}
好吧,我以前从未使用过它,所以我想我会尝试一下。基本上,您只需将转义字符 (ASCII 27) 后跟左括号 [,然后将代码 as described on this page 直接放入字符串中。
为了使这更容易,我编写了一个格式化字符串的函数:
function Format-AnsiColor {
[CmdletBinding()]
[OutputType([String])]
param(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[AllowEmptyString()]
[String]
$Message ,
[Parameter()]
[ValidateSet(
'normal display'
,'bold'
,'underline (mono only)'
,'blink on'
,'reverse video on'
,'nondisplayed (invisible)'
)]
[Alias('attribute')]
[String]
$Style ,
[Parameter()]
[ValidateSet(
'black'
,'red'
,'green'
,'yellow'
,'blue'
,'magenta'
,'cyan'
,'white'
)]
[Alias('fg')]
[String]
$ForegroundColor ,
[Parameter()]
[ValidateSet(
'black'
,'red'
,'green'
,'yellow'
,'blue'
,'magenta'
,'cyan'
,'white'
)]
[Alias('bg')]
[String]
$BackgroundColor
)
Begin {
$e = [char]27
$attrib = @{
'normal display' = 0
'bold' = 1
'underline (mono only)' = 4
'blink on' = 5
'reverse video on' = 7
'nondisplayed (invisible)' = 8
}
$fore = @{
black = 30
red = 31
green = 32
yellow = 33
blue = 34
magenta = 35
cyan = 36
white = 37
}
$back = @{
black = 40
red = 41
green = 42
yellow = 43
blue = 44
magenta = 45
cyan = 46
white = 47
}
}
Process {
$formats = @()
if ($Style) {
$formats += $attrib[$Style]
}
if ($ForegroundColor) {
$formats += $fore[$ForegroundColor]
}
if ($BackgroundColor) {
$formats += $back[$BackgroundColor]
}
if ($formats) {
$formatter = "$e[$($formats -join ';')m"
}
"$formatter$_"
}
}
用法:
Format-AnsiColor -Message 'Hey there' -Style Bold -ForegroundColor Red
'Hello' | Format-AnsiColor -BackgroundColor Green
'One','Two','Three' | Format-AnsiColor -Style 'normal display' -ForegroundColor White -BackgroundColor Black
请记住,如果您不再需要它,则必须关闭序列(我的意思是将样式和颜色设置回原来的样子)。
【讨论】:
Write-Host 或管道..仅此而已我现在可以做。
$PSDefaultParameterValues,或者你可以在参数声明中将前景色的默认值指定为红色:$ForegroundColor = 'red' ,。