user606723
user606723

Reputation: 5125

How to retain colors when using Tee-Object in powershell?

I've written a python script with colored output. I have a powershell script to automate its execution and save its output, like follows:

$python = "path\to\python"
& $python main.py | Tee-Object -FilePath "$logfile"

If I remove the Tee-Object part, the colors show through just fine. In case it matters: For color output, I am using colorama and termcolor python modules.

Does anyone have any suggestions for how to workaround this problem?

Upvotes: 4

Views: 1628

Answers (2)

mklement0
mklement0

Reputation: 437111

Your own answer shows an effective solution via Start-Transcript.[1]

As for the cause of your problem:

It isn't Tee-Object that strips the colors, but the Python script itself, presumably because the modules you use for coloring detect that output isn't being sent to the screen (terminal).

This behavior is by design: the rationale is that if you send something to a file or through a pipeline, you're interested only in the raw text information, not the coloring. Some Unix utilities allow you to override this default behavior with command-line options (e.g., GNU grep has --color=always).

The coloroma module seems to have such an override feature too (haven't looked at termcolor), via its init() function (init(strip=False)) - however, you wouldn't want to hard-wire this behavior into your scripts, so perhaps implementing a command-line option similar to what GNU grep does is an option.

A quick demonstration of the fact that Tee-Object indeed passes VT (Virtual Terminal) sequences / ANSI color codes through:

# The VT escape sequences (ANSI codes) *are* sent to log.txt
# Prints the word "green" in green, both instantly and when calling
# Get-Content log.txt later.
"It ain't easy being $([char] 27)[32mgreen$([char] 27)[m." | Tee-Object log.txt

Caveat:

  • In Windows PowerShell (up to version 5.1) - at least with colorama output - empty lines are filled in with the background color then in effect when they pass through Tee-Object, because the output-formatting system pads output lines with spaces.

  • PowerShell (Core) 7+ no longer has this problem.


[1] The solution is effective in Windows PowerShell. In PowerShell (Core), up to at least v7.3.6, Start-Transcript invariably strips out VT/ANSI escape sequences, even with $PSStyle.OutputRendering = 'Ansi' in effect. See GitHub issue #11567 for a discussion.

Upvotes: 2

user606723
user606723

Reputation: 5125

I am having good luck using Start-Transcript to keep the output instead of Tee-Object.

Start-Transcript -path "$logfile"
& $python main.py
Stop-Transcript

I am not sure if Tee-Object is stripping out the colors, or the colors aren't getting output correctly because Tee-Object is not a tty, but this bypasses either issue.

Upvotes: 3

Related Questions