批处理文件:将变量设置为函数调用的返回值

时间:2019-05-24 22:42:28

标签: batch-file cmd

请问我在这里做错了什么?我想制作一个窗口batch file,该窗口将调用exe,传入一些参数并将返回值分配给变量。我尝试了以下多种变体,但无法使其正常工作。

SET EXE="path\to\exe"
SET TARGET_FILE="path\to\file\to\be\read\by\exe"

for /f %%i in (%EXE% -arg1 %TARGET_FILE%) do set VAR=%%i

ECHO %VAR%
PAUSE

我想念什么? 如果很重要,上面的两个路径可能会包含空格,行C:\Program Files\etc

2 个答案:

答案 0 :(得分:1)

以下批处理文件应该起作用。我还没有测试,请告诉我是否没有。

SET EXE="path\to\exe"
SET TARGET_FILE="path\to\file\to\be\read\by\exe"

for /f "delims=" %%i in ('"%EXE% -arg1 %TARGET_FILE%"') do (
echo %%i
)

答案 1 :(得分:1)

首先,请阅读我在Why is no string output with 'echo %var%' after using 'set var = text' on command line?上的答案,如果在环境变量的定义中第一个双引号留在变量名或右等号的话,将会有很大的不同。另请参见How to set environment variables with spaces?

让我们看一下这段代码:

@echo off
set "Executable=path\to\exe"
set "TargetFile=path\to\file\to\be\read\by\exe"

for /F delims^=^ eol^= %%I in ('"%Executable%" -arg1 "%TargetFile%" 2^>^&1') do set "Data=%%I" & goto HaveData

echo No data captured!
pause
goto :EOF

:HaveData
echo Data: %Data%
pause

FOR ,选项/F的字符串用圆括号括起来并用单引号引起来,导致在背景cmd.exe /c中开始使用%ComSpec% /c并将字符串用圆括号作为附加参数。因此, FOR 在后台启动了另一个命令过程,以执行括号内' ... '之间的指定命令行。

首先将完全限定的文件名分配给环境变量,而在此字符串中不需要使用双引号,该字符串包含空格或以下字符之一&()[]{}^=;!'+,`~。因此,现在必须将环境变量Executable的引用括在双引号中。对于TargetFile,需要执行相同的操作。

FOR 捕获为处理启动命令过程的 STDOUT 而编写的所有内容,以便在启动cmd.exe自身终止后逐行进行最终处理。用于处理 STDERR 的输出也由 FOR 捕获,但是只是重定向到执行批处理文件的命令进程的 STDERR ,因此将只是显示在控制台窗口中。

但是可执行文件可能会输出感兴趣的信息来处理 STDERR ,而不是 STDOUT 。因此,Microsoft在有关using command redirection operators的文章中使用2>&1来获取写入到 STDERR 的可执行文件的输出,并将其重定向到后台命令的 STDOUT 过程。

在Windows命令解释器处理时,重定向操作符>&必须在 FOR 命令行上使用脱字符号^进行转义,才能被解释为文字字符。在执行命令 FOR 之前使用此命令行,该命令将在后台启动的单独命令进程中执行嵌入式命令行。

FOR 逐行处理捕获的输出,并在启动可执行文件完成并因此cmd.exe启动完成之后跳过所有空行。

默认情况下,以;开头的行也会被 FOR 忽略,因为分号是默认的行尾字符。 eol=被指定为不定义任何行尾字符,以避免忽略任何非空行。

FOR 默认情况下使用正常的空格和水平制表符作为字符串定界符,将一行分割为子字符串(令牌)。在此很可能不需要这种字符串拆分行为。因此,为空的定界符列表指定了delims=,以禁用行拆分行为,并被分配给指定的循环变量I,由 FOR 当前处理的整个非空行

for /F之后的选项列表通常使用"一个或多个选项"来指定。在此处无法定义分隔符没有行尾字符的空列表。因此,指定的选项未包含在双引号引起来的字符串中。但是在这种情况下,=和空格必须通过^进行转义,以便通过cmd.exe解析此 FOR 命令行以将其解释为文字字符而不是参数分隔符。将delims= eol=作为一个参数字符串传递给命令 FOR

因此,如果使用环境变量Executable定义的可执行文件仅在ANSI中输出一个非空行,则该行将分配给环境变量Data

但是,也许可执行文件不是以ASCII / ANSI而是以UTF-16 Little Endian编码的Unicode输出感兴趣的信息,并另外输出两个或多个空行,例如wmic.exe。在这种情况下,必须考虑 FOR 在解释Unicode编码输出时的错误,这会导致在 FOR上定义了感兴趣的数据后导致环境变量Data的删除。 在捕获的Unicode输出末尾处理错误的UTF-16 LE编码的空行。有关 FOR 错误的详细信息,请参见How to correct variable overwriting misbehavior when parsing output?,此处使用的解决方案是通过跳转到代码将第一条非空行分配给环境变量Data后离开循环标签HaveData下方。

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • echo /?
  • for /?
  • goto /?
  • pause /?
  • set /?