The CLI doesn't respect `$PSStyle.OutputRendering = 'Host'`, outputs ANSI/VT escape sequences unconditionally · Issue #20170 · PowerShell/PowerShell · GitHub
Skip to content

The CLI doesn't respect $PSStyle.OutputRendering = 'Host', outputs ANSI/VT escape sequences unconditionally #20170

Open

Description

Prerequisites

Steps to reproduce

The purpose of $PSStyle.OutputRendering = 'Host' (Host is the default value) is to use ANSI/VT sequences (for colored output) only when printing to the host (display), but not when command output is captured or redirected.

While this works in-session, the CLI currently always uses ANSI sequences (i.e. it behaves as if $PSStyle.OutputRendering = 'Ansi' were in effect).

Specifically, the CLI doesn't modify its behavior based on whether its stdout stream is connected to a terminal or not (which is the analog to the in-session behavior):

# On Windows, from cmd.exe
pwsh -noprofile -c $PSVersionTable | findstr .

# On Unix, from Bash, for instance
pwsh -noprofile -c '$PSVersionTable' | cat

Note:

  • While programmatically processing for-display formatted output via text parsing isn't recommended, it still shouldn't be made harder by including ANSI sequences in the output text.

  • Correcting the behavior as suggested would then require an in-session $PSStyle.OutputRendering = 'Ansi' call in the case colored output is desired when captured/redirected; ideally, there'd be a CLI parameter as an alternative, analogous to the --color=always option that GNU utilities such as ls and grep support.

  • Somewhat accidentally, Write-Host with -ForegroundColor / BackgroundColor already behaves this way, albeit unconditionally - see Make colored Write-Host calls (-ForegroundColor / -BackgroundColor) emit ANSI/VT sequences when stringified, notably in CLI output #20171

Expected behavior

Uncolored output

Actual behavior

Colored output (the column headers are colored - see below)

Error details

No response

Environment data

PowerShell 7.4.0-preview.5

Visuals

image

Activity

  1. 237dmitry commented on Aug 26, 2023

    @237dmitry

    Expected behavior

    I do not understand why it should be uncolored? Is this hard to set $PSStyle.OutputRendering = 'PlainText' before outputing or redirecting? This task is not very often required, in my practice in several scripts that output table to file.

  2. mklement0 commented on Aug 26, 2023

    @mklement0
    ContributorAuthor

    When the value is Host, coloring should only be applied when outputting to the host (terminal) - it shouldn't make a difference whether output is session-internal, to the success-output stream, or session-external to stdout; e.g, pwsh -noprofile -c '$PSVersionTable | Out-String' | cat produces uncolored output.

    This is not just a matter of consistency, but is sensible behavior that is typical for many external CLIs, such as the GNU utilities that come with Linux.

  3. 237dmitry commented on Aug 26, 2023

    @237dmitry

    but is sensible behavior that is typical for many external CLIs

    There are many other examples of different behavior.

    For example Out-String outputs single string of lines and pwsh understand it as is, but native utilities do not understand multiline string:

    $PSVersionTable | Out-String | wc -l    # 14
    ($PSVersionTable | Out-String).Count    # 1
    
  4. mklement0 commented on Aug 26, 2023

    @mklement0
    ContributorAuthor

    Your example has nothing to do with this issue, which is about conditional coloring depending on whether the success stream / stdout is connected to a host / terminal or not and its consistent application.
    (Of course there are many differences between PowerShell and external utilities, but there are also commonalities, and this is one, and it should act consistently.)

  5. 237dmitry commented on Aug 26, 2023

    @237dmitry

    conditional coloring depending on whether the success stream / stdout is connected to a host / terminal or not and its consistent application.

    I think $PSStyle.OutputRendering works properly. But I do not understand when ))

    ss

    PS. And I think Write-Host shouldn't output any data to the pipe at all. As it says in the help:

    The Write-Host cmdlet's primary purpose is to produce for-(host)-display-only output...

  6. mklement0 commented on Aug 28, 2023

    @mklement0
    ContributorAuthor

    All the in-session behaviors you're showing are as designed.

    By contrast, this issue is about the behavior of the CLI (and, with a *>&1 or 6>&1 redirection in-session, also the behavior of Out-String):

    Write-Host shouldn't output any data to the pipe at all.

    • Indeed it shouldn't and it doesn't.

    • However, in a CLI call, Write-Host output is sent to stdout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageThe issue is new and needs to be triaged by a work group.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions