In PowerShell, is there a way to preserve the ANSI control codes used to convey color information to the console when assigning a program's output to a variable?
For instance, I use Test Kitchen which provides colored output unique to each suite of tests to run. When I run kitchen create INSTANCE
, I get output in several colors. However, if I assign the output to a variable, or pipe it to another cmdlet such as Tee-Object
, that color information is lost. It seems that PowerShell strips this information out when the result is sent down the pipeline or assigned to a variable:
kitchen create INSTANCE # Colored output
$output = kitchen create INSTANCE
Write-Host $output # Color information is lost
Curiously though, I can implement control codes in my own strings and PowerShell is able to honor them when Virtual Terminal is enabled. These survive variable assignment, unlike command output:
$output = "`u{001b}[31mHello"
Write-Host $output # Results in colored output
So it seems that the color information is being stripped out only from a program's output, and only if the value is assigned or sent down the pipeline. Is there a way to preserve these control codes from external commands?
CodePudding user response:
As mentioned by @IMSoP and @mklement0 in the question comments, the problem does not lie within PowerShell. To quote @mklement0:
PowerShell is not to blame here. Most utilities (external programs) that are capable of colored output via ANSI escape sequences at least by default apply coloring selectively, namely only when stdout is connected to a terminal (i.e. when printing to the display). Such utilities may offer opt-in mechanisms to apply coloring unconditionally, via command-line options and/or environment variables.
CodePudding user response:
To add to your own answer:
On Windows I'm not aware of any simple solutions, though perhaps there is a programmatic way to do what the
script
utility does on Unix-like platforms (see below).On Unix-like platforms, you can use the
script
utility to make external programs believe they are connected to a terminal and thus make them produce colored output they would otherwise suppress:script
is not a POSIX-mandated utility, but it ships with at least some Linux distros, notably Ubuntu, as well as with macOS.- Notably, the macOS and Linux implementations use different syntax, as shown below.
Example:
Note:
ls --color=auto
is used as a readily available test command, because it exhibits the conditional coloring behavior.ls --color=always
would exhibit unconditional coloring behavior, and would therefore obviate the need forscript
- as such,ls
is an example of a utility that does allow you to request unconditional coloring;ls --color=auto
merely serves as a stand-in for utilities that do not.The variable assignment below (
$out = ...
) is enclosed in(...)
in order to pass the value being assigned through, so you'll see right away that the coloring is preserved.
Linux
($out = script -qc 'ls --color=auto')
- macOS:
($out = script -q /dev/stdout ls --color=auto)