为什么将命令输出重定向到变量在批处理文件中不起作用
Why directing output of command to a variable doesnt work in batch file
我试图将命令 python --version
的输出分配给批处理脚本中的一个变量,但它不起作用。
这是我使用的示例代码
FOR /F "tokens=* USEBACKQ" %%F IN (`python --version`) DO (
SET message=%%F
)
ECHO %message%
虽然它打印了 python 的版本,但它没有分配给变量 var
。
如果我使用另一个命令而不是 python --version
则输出被正确分配。例如使用 dir
有效。
有什么问题吗?
注意-
@echo off
set message=Hello
FOR /F "tokens=* USEBACKQ" %%F IN (`python --version`) DO (
SET message=%%F
)
ECHO %message%
PAUSE
输出-
C:\Users\nik>extra.bat
Python 2.7.9
Hello
Press any key to continue . . .
安装的Python版本显然输出版本信息来处理STDERR(标准错误)而不是处理STDOUT (标准输出)。因此,有必要使用 2>&1
将带有版本信息的标准错误流重定向到标准输出流,如 Microsoft 在有关 Using command redirection operators.
的文档中所述
要使用的命令行是:
for /F "delims=" %%I in ('python.exe --version 2^>^&1') do set "message=%%I"
重定向运算符 >
和 &
必须在 FOR 命令行上使用脱字符 ^
进行转义,以被解释为文字字符当 Windows 命令解释器在执行命令 FOR.
之前处理此命令行时
FOR 分别 cmd.exe
使用此命令行处理批处理文件在后台启动另一个命令进程 %ComSpec% /c
并且命令行在 '
作为附加参数附加。因此在后台将 Windows 安装到 C:\Windows
中执行:
C:\Windows\System32\cmd.exe /c python.exe --version 2>&1
后台命令进程现在搜索可执行文件 python.exe
,如 所述 当文件 python.exe
可以被 cmd.exe
运行 找到时在没有可见控制台的后台 window,它执行它并且 Python 将版本信息输出到标准错误流,标准错误流被重定向到后台命令进程的标准输出流。
启动的 cmd.exe
在打印版本信息后 python.exe
自行终止后自行关闭。
处理批处理文件的 cmd.exe
实例捕获为处理已启动的后台命令进程和 FOR 进程的 STDOUT 编写的所有内容开始后捕获的行 cmd.exe
自行关闭。
默认情况下 将非空捕获行拆分为子字符串,使用普通 space 和水平制表符作为字符串分隔符。如果删除 0 个或多个前导后的第一个子字符串 spaces/tabs 以分号开头,则捕获的行将被忽略,否则将第一个子字符串分配给指定的循环变量 I
.
这里不需要默认的行处理行为。出于这个原因,for /F
选项 delims=
定义了一个空的字符串定界符列表,以禁用行拆分行为,从而将整个捕获的行分配给指定的循环变量 I
。在这种情况下可以保留隐式默认值 eol=;
(分号是行尾),因为 Python 输出的版本信息从不以分号开头。
我试图将命令 python --version
的输出分配给批处理脚本中的一个变量,但它不起作用。
这是我使用的示例代码
FOR /F "tokens=* USEBACKQ" %%F IN (`python --version`) DO (
SET message=%%F
)
ECHO %message%
虽然它打印了 python 的版本,但它没有分配给变量 var
。
如果我使用另一个命令而不是 python --version
则输出被正确分配。例如使用 dir
有效。
有什么问题吗?
注意-
@echo off
set message=Hello
FOR /F "tokens=* USEBACKQ" %%F IN (`python --version`) DO (
SET message=%%F
)
ECHO %message%
PAUSE
输出-
C:\Users\nik>extra.bat
Python 2.7.9
Hello
Press any key to continue . . .
安装的Python版本显然输出版本信息来处理STDERR(标准错误)而不是处理STDOUT (标准输出)。因此,有必要使用 2>&1
将带有版本信息的标准错误流重定向到标准输出流,如 Microsoft 在有关 Using command redirection operators.
要使用的命令行是:
for /F "delims=" %%I in ('python.exe --version 2^>^&1') do set "message=%%I"
重定向运算符 >
和 &
必须在 FOR 命令行上使用脱字符 ^
进行转义,以被解释为文字字符当 Windows 命令解释器在执行命令 FOR.
FOR 分别 cmd.exe
使用此命令行处理批处理文件在后台启动另一个命令进程 %ComSpec% /c
并且命令行在 '
作为附加参数附加。因此在后台将 Windows 安装到 C:\Windows
中执行:
C:\Windows\System32\cmd.exe /c python.exe --version 2>&1
后台命令进程现在搜索可执行文件 python.exe
,如 python.exe
可以被 cmd.exe
运行 找到时在没有可见控制台的后台 window,它执行它并且 Python 将版本信息输出到标准错误流,标准错误流被重定向到后台命令进程的标准输出流。
启动的 cmd.exe
在打印版本信息后 python.exe
自行终止后自行关闭。
处理批处理文件的 cmd.exe
实例捕获为处理已启动的后台命令进程和 FOR 进程的 STDOUT 编写的所有内容开始后捕获的行 cmd.exe
自行关闭。
默认情况下 将非空捕获行拆分为子字符串,使用普通 space 和水平制表符作为字符串分隔符。如果删除 0 个或多个前导后的第一个子字符串 spaces/tabs 以分号开头,则捕获的行将被忽略,否则将第一个子字符串分配给指定的循环变量 I
.
这里不需要默认的行处理行为。出于这个原因,for /F
选项 delims=
定义了一个空的字符串定界符列表,以禁用行拆分行为,从而将整个捕获的行分配给指定的循环变量 I
。在这种情况下可以保留隐式默认值 eol=;
(分号是行尾),因为 Python 输出的版本信息从不以分号开头。