首页 > 解决方案 > 当管道输出到“查找”时,路径名中的空格会导致问题

问题描述

当路径有空格或使用变量时,无法使用 %var% 测试程序的输出尝试了以下脚本,只有最后一个有效(任务数为“0”)

SET MYTEST1="C:\Program Files\Boinc\"
SET MYTEST2="C:\Progra~1\Boinc\"

FOR /F "tokens=* USEBACKQ" %%F IN (`%MYTEST1%boinccmd.exe --get_tasks ^| find /i /c "executing"`) DO (
SET NumMasterTasks=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`%MYTEST2%boinccmd.exe --get_tasks ^| find /i /c "executing"`) DO (
SET NumMasterTasks=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`C:\Program Files\boinc\boinccmd.exe --get_tasks ^| find /i /c "executing"`) DO (
SET NumMasterTasks=%%F
)


FOR /F "tokens=* USEBACKQ" %%F IN (`C:\Progra~1\Boinc\boinccmd.exe --get_tasks ^| find /i /c "executing"`) DO (
SET NumMasterTasks=%%F
)

这是输出:

C:\Program Files\BOINC>SET MYTEST1="C:\Program Files\Boinc\"
C:\Program Files\BOINC>SET MYTEST2="C:\Progra~1\Boinc\"

C:\Program Files\BOINC>FOR /F "tokens=* USEBACKQ" %F IN (`"C:\Program Files\Boinc\"boinccmd.exe --get_tasks | find /i /c "executing"`) DO (SET NumMasterTasks=%F )
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

C:\Program Files\BOINC>FOR /F "tokens=* USEBACKQ" %F IN (`"C:\Progra~1\Boinc\"boinccmd.exe --get_tasks | find /i /c "executing"`) DO (SET NumMasterTasks=%F )
The filename, directory name, or volume label syntax is incorrect.

C:\Program Files\BOINC>FOR /F "tokens=* USEBACKQ" %F IN (`C:\Program Files\boinc\boinccmd.exe --get_tasks | find /i /c "executing"`) DO (SET NumMasterTasks=%F )
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

C:\Program Files\BOINC>FOR /F "tokens=* USEBACKQ" %F IN (`C:\Progra~1\Boinc\boinccmd.exe --get_tasks | find /i /c "executing"`) DO (SET NumMasterTasks=%F )

C:\Program Files\BOINC>(SET NumMasterTasks=0 )

一个有效的有两个问题:我想将变量用于路径而不是硬代码路径,并且不方便的是,“程序文件”并不总是“Progra~1”,如

 Directory of Y:\

11/04/2019  10:12 AM    <DIR>                       .
11/04/2019  10:11 AM    <DIR>                       ..
11/04/2019  10:11 AM    <DIR>          PL6FPL~Q     Program Files
11/04/2019  10:12 AM    <DIR>          PT8A6Y~T     Program Files (x86)
               0 File(s)              0 bytes
               4 Dir(s)  4,778,356,477,952 bytes free

尝试了以下(感谢斯蒂芬!)

SET "ROOTBIN=C:\Progra~1\boinc\"
FOR /F "tokens=* USEBACKQ" %%F IN (`%ROOTBIN%boinccmd.exe --get_tasks ^| find /i /c "executing"`) DO (
SET NumMasterTasks=%%F
)

但是,我使用了 Program Files 的短名称,如果我使用带有该空格的名称,脚本将失败。

C:\Program Files\BOINC>SET "ROOTBIN=C:\Progra~1\boinc\"

C:\Program Files\BOINC>FOR /F "tokens=* USEBACKQ" %F IN (`C:\Progra~1\boinc\boinccmd.exe --get_tasks | find /i /c "executing"`) DO (SET NumMasterTasks=%F )

C:\Program Files\BOINC>(SET NumMasterTasks=30 )

标签: windowscmd

解决方案


只要您有文件夹或文件名,就必须引用完整的结构。
使用变量时,最佳做法是使用推荐的语法set "var=value"。引号确保所有属于一起的,保持在一起。(作为额外的好处,它还可以与“毒字符”(如&<>)一起使用,而无需逃避它们)。
使用这种语法,引号不是值的一部分,因此您必须稍后引用字符串(这确保您可以完全控制稍后在代码中引用的内容)

删除路径尾随\只是个人喜好 - 我发现代码可读性更好("%ROOTBIN%boinccmd.exe"vs. "%ROOTBIN%\boinccmd.exe"

usebackq使用正确的引号时,您实际上并不需要在这里。tokens=*这里也不需要,因为只返回一个| find /c没有任何空格或其他文本的数字。

由于管道,事情发生了一些变化。以下代码应该可以工作(使用... in ('" "command"|command "') do ...而不是试图转义正确的部分):

SET "ROOTBIN=C:\Program Files\Boinc"
FOR /F %%F IN ('" "%ROOTBIN%\boinccmd.exe" --get_tasks | find /i /c "executing" "') DO (
    SET NumMasterTasks=%%F
)
echo %NumMasterTasks%

推荐阅读