пробелы в имени пути вызывают проблемы при передаче вывода в "find" - PullRequest
0 голосов
/ 04 ноября 2019

Невозможно проверить вывод программы, используя% 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 )

Есть две проблемы с той, которая работает: я хочу использовать переменные для путей, а не пути жесткого кода и, неудобно, "Program Files" не всегда "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 )

1 Ответ

1 голос
/ 04 ноября 2019

Всякий раз, когда у вас есть имя папки или файла, необходимо заключить в кавычку complete .
При использовании переменных рекомендуется использовать рекомендуемый синтаксис set "var=value". Цитаты гарантируют, что все, что принадлежит вместе, остается вместе. (В качестве дополнительного преимущества, он также работает с «ядом символов» (например, &<>) без необходимости экранировать их).
С этим синтаксисом кавычки не часть значения, поэтомуВы должны процитировать строку позже (это гарантирует, что у вас есть полный контроль над тем, что цитировать позже в коде)

Удаление конечного \ с путем - просто личное предпочтение - я нахожу кодчтобы быть лучше читаемым ("%ROOTBIN%boinccmd.exe" против "%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%
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...