从 Python 2 返回 --version check 和 Python 3 的区别

jay*_*are 2 python cmd batch-file python-2.x python-3.x

为什么--version在 Python 2 上运行检查的结果与在 Python 3 上的表现不同?下面是将输出写入文本文件并随后检查该文件的内容时的两种行为示例。

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>
Run Code Online (Sandbox Code Playgroud)

有没有办法产生与 Python 3 相同的行为?我想使用--versioncheck 命令的输出作为批处理文件的一部分,以确保使用正确的版本来执行脚本。

asc*_*pfl 5

Python 2 似乎将版本信息输出到STDERR (handle 2) 而不是STDOUT (handle 1),因此更改:

C:\Python27\python.exe --version >> file2.txt
Run Code Online (Sandbox Code Playgroud)

到:

C:\Python27\python.exe --version 2> file2.txt
Run Code Online (Sandbox Code Playgroud)

重定向操作符>>是用来追加到文件; 要(覆盖)写入,请>改用。

要将STDOUTSTDERR写入文件,请使用以下命令(替换??2734):

C:\Python??\python.exe --version > "file.txt" 2>&1
Run Code Online (Sandbox Code Playgroud)

该表达式2>&1表示将句柄重定向到句柄2的当前目标1,这是由于> "file.txt". 请注意,这>等效于1>,因为输出重定向的默认句柄是1( STDOUT )。顺序在这里很重要(所以2>&1 > "file.txt"会失败)。

这在附加到文件时也有效:

C:\Python??\python.exe --version >> "file.txt" 2>&1
Run Code Online (Sandbox Code Playgroud)

要在没有(临时)文件的情况下将结果直接放入变量中,请在使用for /F循环

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

并在

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

请注意转义使用^是必要的,以避免过早尝试重定向。

要仅将纯版本号存储到变量中而没有Python前面的单词,请替换delims=tokens=2


让我们更进一步:您可以让自行搜索所有可用的 Python 版本。鉴于包含python.exe系统变量PATH中的目录路径,您可以使用where获取可执行文件的完整路径,然后for /F循环遍历它们以获取它们的确切版本(版本号只是为了演示而在此处回显):

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

如果PATH变量不包含路径,您也可以C:\Python??使用for /D(这里??的字面意思是通配符)搜索所有路径;where只是检查是否真的有一个文件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
        )
    )
)
Run Code Online (Sandbox Code Playgroud)