【问题标题】:Retrieve command output to variable when command has spaces当命令有空格时将命令输出检索到变量
【发布时间】:2015-10-27 14:39:51
【问题描述】:

我在很多地方读到过,我可以使用 Windows 批处理文件 for 来获取命令的输出并将其放入变量中,如下所示:

FOR /F %%G IN ('foo-command') DO SET FOO=%%G

太好了。所以我的foo-command 实际上是C:\Program Files\Foo\foo.bat,它存储在FOO_BAT 变量中。它接受一个参数bar,其值为blah blah='foobar' blah。所以我试试:

FOR /F %%G IN ('%FOO_BAT% -bar "blah blah='foobar' blah"') DO SET FOO=%%G

我收到了一个可爱的'C:\Program' is not recognized...。我无能为力地绕过命令中的空间。

如果您想重现此内容,请创建一个简单的 C:\Program Files\Foo\foo.bat 文件,其中仅包含以下内容,然后在批处理文件中运行上述行。

echo FooBar

如果命令的路径中有空格,我如何将命令(接受参数)的输出捕获为 Windows 批处理变量?

  • 是的,我尝试在 %FOO_EXE% 周围加上引号。
  • 是的,我尝试将所有内容放在一个单独的变量中,并在 FOR 中使用该单个变量。
  • 在告诉我它有效之前,请使用我提供的参数尝试。参数的存在改变了一切。

【问题讨论】:

  • 您需要在“%FOO_EXE%”变量周围加上引号。
  • @Squashman 我猜你错过了我说“是的,我尝试在 %FOO_EXE% 周围加上引号”的部分。
  • 编辑您的原始问题并在可执行文件周围使用 QUOTES 时尝试的确切用法。单词 program 后面有一个空格,因此您没有根据您提供的 ERROR 正确使用引号。
  • @Squashman 请自己尝试FOR /F %%G IN ('"C:\Program Files\Foo\foo-command.exe" -bar "blah blah='foobar' blah"') DO SET FOO=%%G,然后告诉我你得到了什么错误。谢谢。
  • @Squashman 我对您在运行上述命令时收到的错误非常感兴趣。你能把它贴在这里给我们所有人吗?谢谢。

标签: windows variables batch-file command


【解决方案1】:

当您尝试直接处理来自FOR 循环的输出时,我建议您包含usebackq 参数。这允许您在命令中包含引号(通常需要)以指定完整的文件路径或其中包含空格的单个参数。

例如:

REM Using the DIR command with FOR switches, extract the short name.
REM The path specified below can be fed by a variable.
FOR /F "usebackq tokens=*" %%G IN (`DIR "C:\Program Files\Foo\foo-command.exe" /B /S`) DO SET FooPathShortName=%%~sG
ECHO Short Name is: %FooPathShortName%

REM No quotes are needed to run the short name.
FOR /F "usebackq" %%G IN (`%FooPathShortName% -bar "blah blah='foobar' blah"`) DO SET Foo=%%G

在上面,我使用DIR 命令将目标可执行文件的完整路径输出为FOR 函数可以解析为文件的格式。由此我确定在第二个FOR 命令中执行不需要空格的文件的短名称。

【讨论】:

  • Jason,你测试过这个理论了吗?
  • @JasonFaulkner 我已阅读帮助。但以下仍然不起作用:FOR /F "usebackq tokens=1,2,* delims= " %%G IN (`"C:\Program Files\Foo\foo-command.exe" -bar "blah blah='foobar' blah"`) DO SET FOO=%%G。说真的,只需复制和粘贴,您就会明白我的意思。
  • @GarretWilson - 我的命令只是一个示例,我已对其进行了更新以更准确地反映您正在尝试执行的操作。请注意我添加的评论。命令本身的原始输出是什么(如果您不在FOR 循环中处理)?这可能会增加一些清晰度。
  • 就像我说的@JasonFaulkner,复制和粘贴,你会看到自己的!你为什么不自己运行你给我的命令?是的,我知道您的机器上没有foo-command.exe,但错误消息将表明Windows 认为该命令是'C:\Program' 而不是'C:\Program Files\Foo\foo-command.exe'。您是否尝试运行您在回答中给我的批处理文件?
  • @GarretWilson - 是的,我刚刚尝试使用 2 个引用参数(显然是不同的工具),它似乎对我有用。我很好奇这对你不起作用......你有什么版本的 Windows(我有 7 个)?您可以做的解决方法是临时附加PATH,这样您就不必引用该命令。查看更新的答案。
【解决方案2】:
FOR /F "delims=" %%G IN ('CALL "C:\path with spaces\foo.bat" "blah blah='foobar' blah"') do set foo=%%G

试试这个。是的,我测试了它。 Foo.bat 仅执行 echo %1。

【讨论】:

  • 好主意!我什至没想过要使用CALL。我相信它也适用于非批处理(在他的情况下为 EXE)文件。
  • @JasonFaulkner,我不想因为以我的 SFK.exe 为例而再次被骂。我喜欢你的短文件名示例。
  • @Squashman,成功了!万岁!!如果有复杂的参数,FOR 似乎对“命令”中的空格非常挑剔。使用CALL 作为“命令”解决了这个问题。太感谢了!我将添加一个赏金,以便我可以将它奖励给这个答案。
  • @JasonFaulkner 我最终没有测试您的答案,因为这个答案有效并且要短得多。但你的看起来确实是个聪明的把戏。感谢您的贡献!
  • @GarretWilson,虽然它可能比 Jason 的脚本更短,但他的脚本实际上可能运行得更快。使用 CALL 总是有一点开销。将脚本减慢一小部分。在这种情况下,它可能不是那么重要,但在大型 LOOP 中使用 CALL 可能会有很大的时间差异。
猜你喜欢
  • 2012-02-15
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 2011-12-31
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
相关资源
最近更新 更多