批处理脚本 - 在命令和 usebackq 中使用带有空格的 FOR /F

Mid*_*ram 6 windows batch-file

批处理脚本非常新。我需要将命令的输出分配给变量。我开始了解 FOR /F 命令。我的命令有空格和双引号。所以我尝试使用 usebackq 选项。但它因空间错误而失败。

for /F "usebackq delims=" %%G IN (`"C:\Program Files (x86)\ABC\DEF\XYZ.exe" Get /a "P1=D2" /b "Q1=D3" /c "D5"`) DO (
SET var=%%G
)

ECHO %var%

pause
Run Code Online (Sandbox Code Playgroud)

失败 :

'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
Run Code Online (Sandbox Code Playgroud)

根据 StackOverflow 上的其他问题,我做的一切都是正确的 - usebackq来使用反勾号,demlims=来忽略空格作为分隔符。我不知道为什么它仍然失败。任何帮助表示赞赏!

Mof*_*ofi 0

\'内或内`使用的命令行由FORusebackq执行,分别带有选项的Windows 命令进程在后台使用 \xc2\xa0 处理批处理文件,并附加作为附加参数的命令行。/Fcmd.exe%ComSpec% /c

\n

ComSpec%SystemRoot%\\System32\\cmd.exe是作为系统环境变量预定义的 Windows 环境变量。

\n

在命令提示符窗口中运行时的帮助输出cmd /?解释了 Windows 命令处理器在选项/C(执行命令行并关闭)或 \xc2\xa0option 之后如何解释字符串/K(执行命令行并继续运行)之后如何解释字符串。

\n

这里不需要使用反引号,因为要执行的命令行不包含其本身\xc2\xa0一个或多个带有\'. 因此可以将命令行包含在\'.

\n

必须考虑FOR执行的命令行,Windows命令解释器如何解析批处理脚本,即通过处理批处理文件来解析和处理FOR命令行后的外观,这可以在调试批处理cmd.exe时看到。文件以及命令行如何作为参数字符串传递到cmd.exe在后台执行的第二个实例。

\n

至少有以下两种解决方案。

\n
for /F "delims=" %%G in (\'^""%ProgramFiles(x86)%\\ABC\\DEF\\XYZ.exe" Get /a "P1=D2" /b "Q1=D3" /c "D5"^"\') do set "var=%%G"\nfor /F "delims=" %%G in (\'""C:\\Program Files (x86^)\\ABC\\DEF\\XYZ.exe" Get /a "P1^=D2" /b "Q1^=D3" /c "D5""\') do set "var=%%G"\n
Run Code Online (Sandbox Code Playgroud)\n

第一个解决方案是由Compo建议的,并且是更简单的解决方案。整个命令行被包含在"其中,cmd.exe在处理和执行剩余的命令行之前,在后台启动的删除。"在命令行开头和结尾额外添加的字符会被转义,以^cmd.exe批处理文件解释为文字字符,而不是参数字符串的开头/结尾。因此,两个转义之间的参数字符串通常通过处理FOR命令行"来解释。cmd.exe

\n

第二种解决方案比较难理解。整个命令行也包含在后台启动中"cmd.exe但是处理批处理文件时不会转义双引号cmd.exe,因此该cmd.exe实例现在将命令行解释为以下参数字符串的列表:

\n
    \n
  1. ""
  2. \n
  3. C:\\Program
  4. \n
  5. Files
  6. \n
  7. (x86
  8. \n
  9. )
  10. \n
  11. \\ABC\\DEF\\XYZ.exe
  12. \n
  13. " Get /a "
  14. \n
  15. P1=D2
  16. \n
  17. " /b "
  18. \n
  19. Q1=D3
  20. \n
  21. " /c "
  22. \n
  23. D5
  24. \n
  25. ""
  26. \n
\n

在这种情况下,后面的右圆括号(x86不会被解释为文字字符,因为它位于用于cmd.exe处理整个FOR命令行的双引号参数字符串之外。因此,在标记要执行的命令行结束之前,必须对其进行转义^,以将其解释为文字字符,而不是放置在错误位置的集合结束。\'

\n

两个等号都位于用于cmd.exe处理批处理文件的双引号参数字符串之外。因此,会将它们解释为参数分隔符,并用空格字符cmd.exe替换它们。=这里不需要这样做,因为参数应该作为P1=D2and传递Q1=D3给可执行文件,而不是作为P1 D2and传递Q1 D3。因此,必须将两个等号转义^为文字字符,而不是通过cmd.exe处理批处理文件作为参数分隔符。

\n

这两种解决方案都会导致在后台运行 Windows,C:\\Windows并将 32 位程序文件安装到C:\\Program Files (x86)

\n
C:\\Windows\\System32\\cmd.exe /c ""C:\\Program Files (x86)\\ABC\\DEF\\XYZ.exe" Get /a "P1=D2" /b "Q1=D3" /c "D5""\n
Run Code Online (Sandbox Code Playgroud)\n

后台命令进程去掉第一个和最后一个"然后运行

\n
"C:\\Program Files (x86)\\ABC\\DEF\\XYZ.exe" Get /a "P1=D2" /b "Q1=D3" /c "D5"\n
Run Code Online (Sandbox Code Playgroud)\n

可以在目录中创建仅包含命令行的C:\\Program Files (x86)\\ABC\\DEF批处理文件,并在包含FOR命令行的批处理文件中替换为,以查看批处理文件是否完全执行以及将哪些参数传递给批处理文件。这有助于了解在命令提示符窗口中使用FOR命令行删除和运行批处理\xc2\xa0文件时发生的情况。XYZ.bat@echo %0 %*.exe.bat@echo off

\n