Difference between return from Python 2 --version check and Python 3

Viewed 83

Why does the return from running the --version check on Python 2 behave differently than that on Python 3? Below is an example of the two behaviors when writing their output to a text file and subsequently checking the contents of that file.

C:\Users\user1>C:\Python27\python.exe --version >> file2.txt
Python 2.7.13

C:\Users\user1>type file2.txt

C:\Users\user1>C:\Python38\python.exe --version >> file3.txt

C:\Users\user1>type file3.txt
Python 3.8.1

C:\Users\user1>

Is there any way to produce the same behavior as Python 3? I would like to use the output from the --version check command as part of a batch file to ensure the proper version is being used to execute a script.

2 Answers

Python 2 seems to output the version information to STDERR (handle 2) rather than STDOUT (handle 1), so change:

C:\Python27\python.exe --version >> file2.txt

to:

C:\Python27\python.exe --version 2> file2.txt

The redirection operator >> is used to append to a file; to (over-)write, use > instead.

To write both STDOUT and STDERR to the file, use this (replace ?? by 27 or 34):

C:\Python??\python.exe --version > "file.txt" 2>&1

The expression 2>&1 means to redirect handle 2 to the current target of handle 1, which is the given text file due to > "file.txt". Note that > is equivalent to 1>, since the default handle for output redirection is 1 (STDOUT). The order is important here (so 2>&1 > "file.txt" would fail).

This works also when appending to a file:

C:\Python??\python.exe --version >> "file.txt" 2>&1

To get the result directly into a variable without a (temporary) file, use a for /F loop – in :

for /F "delims=" %V in ('C:\Python??\python.exe --version 2^>^&1') do set VAR=%V

and in a :

for /F "delims=" %%V in ('C:\Python??\python.exe --version 2^>^&1') do set VAR=%%V

Note the escaping using ^ that is necessary to avoid the redirection to be attempted too early.

To store only the pure version number into the variable without the word Python in front, replace delims= by tokens=2.


Let us even go a step further: You could let a search all available Python versions on its own. Given that the directory paths containing python.exe are listed in the system variable PATH, you could use where to get the full paths to the executables, then let for /F loop through them to get their exact versions (the version number is simply echoed out here just for demonstration):

@echo off
for /F "delims=" %%W in ('where python') do (
    for /F "tokens=2" %%V in ('"%%W" --version 2^>^&1') do (
        echo %%V
    )
)

If the PATH variable does not contain the paths, you could alternatively search all paths C:\Python?? using for /D (here ?? is meant literally as wildcards); where just checks whether there is actually a file python.exe:

@echo off
for /D %%X in ("%SystemDrive%\Python??") do (
    for /F "delims=" %%W in ('where "%%~X":python 2^> nul') do (
        for /F "tokens=2" %%V in ('"%%W" --version 2^>^&1') do (
            echo %%V
        )
    )
)
Related