powershellstdoutsubcommand

Command output printed instead of captured in Powershell


In general, I know how to capture the output of a command into a variable in Powershell:

> $output = python3 --version
> Write-Host $output
Python 3.7.0

Python 3 prints its version but it's captured into the variable $output and nothing is displayed on the console. As expected:

> $output = python3 --version
> Write-Host $output
Python 3.7.0

But in the case of Python 2, it doesn't work. Python 2 prints its version but its displayed on the console instead of captured and the variable $output is empty.

> $output = python2 --version
Python 2.7.15
> Write-Host $output

>

I have tried some alternative syntaxes but so far nothing helped:

> $output = (python2 --version)  # use a subcommand
Python 2.7.15
> $output = "$(python2 --version)"  # enclose the subcommand into a string
Python 2.7.15

If I use it in Write-Command, the output looks like the following:

> Write-Host "Python version: $(python2 --version)"
Python 2.7.15
Python version:
>

How is Python 2 printing its version that it's not captured into a variable and is it possible to capture it anyhow?


Solution

  • It's caused by Python 2 which prints version to stderr instead of stdout. Assignment of program call's output captures stdout only which is empty in this case. On the other side, stderr is printed to the console by default, that's why the $output variable is empty and the version is printed to the console. See below for details.

    tl; dr:

    # Redirect stderr to the success output stream and convert to a string.
    $output = (python --version 2>&1).ToString()
    # $? is now $True if python could be invoked, and $False otherwise
    

    For commands that may return multiple stderr lines, use:


    Note: