为啥将命令输出定向到变量在批处理文件中不起作用

Posted

技术标签:

【中文标题】为啥将命令输出定向到变量在批处理文件中不起作用【英文标题】:Why directing output of command to a variable doesnt work in batch file为什么将命令输出定向到变量在批处理文件中不起作用 【发布时间】:2021-11-24 03:32:58 【问题描述】:

我正在尝试将命令 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 . . .

【问题讨论】:

在这种情况下,尝试将输出重定向到NUL,例如python --version > NUL。如果您仍然可以看到版本,则程序不会输出到 stdout 好主意,但我不能在上面的代码中使用> NUL 重定向。此外,除了python --version 之外,其他命令的输出可以分配给变量 @nik 为什么不呢?无需重定向的任何方式,您的代码在我的 PC 上都可以正常工作 变量未定义时如何输出版本? echo %var% 是代码中唯一输出到屏幕的内容。 没有。打开命令行窗口,然后在命令提示符下键入:python --version > test.txt 不要运行您的 .bat 文件! 【参考方案1】:

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 分别使用此命令行处理批处理文件的cmd.exe 在后台启动另一个命令进程,其中%ComSpec% /c' 中指定的命令行作为附加参数附加。因此在后台安装到C:\Windows 的Windows 中执行:

C:\Windows\System32\cmd.exe /c python.exe --version 2>&1

后台的命令进程现在搜索可执行文件python.exe,如What is the reason for "X is not recognized as an internal or external command, operable program or batch file"? 所述,当python.exe 可以在后台运行而没有可见控制台窗口的cmd.exe 找到文件时,它会执行它并 Python 输出标准错误流的版本信息被重定向到后台命令进程的标准输出流。

已启动的cmd.exe 在打印版本信息后python.exe 自行关闭后自行关闭。

处理批处理文件的cmd.exe 实例捕获为处理启动的后台命令进程的STDOUT 而编写的所有内容,FOR 在启动cmd.exe 关闭后处理捕获的行.

默认使用普通空格和水平制表符作为字符串分隔符将非空捕获的行拆分为子字符串。如果删除 0 个或多个前导空格/制表符后的第一个子字符串以分号开头,则忽略捕获的行,否则将第一个子字符串分配给指定的循环变量 I

这里不需要默认的行处理行为。出于这个原因,for /F 选项delims= 定义了一个空的字符串分隔符列表,以禁用行拆分行为,从而将整个捕获的行分配给指定的循环变量I。在这种情况下,可以保留隐式默认 eol=;(分号是行尾),因为 Python 输出的版本信息从不以分号开头。

【讨论】:

以上是关于为啥将命令输出定向到变量在批处理文件中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

echo 变量在批处理文件中不起作用

环聊api json在批处理脚本中不起作用

为啥页面重定向在 php 中不起作用

批处理之命令重定向操作

如何在批处理中输入文字,然后再输出到文本中?

数据库查询在批处理文件中不起作用