Во-первых, пожалуйста, прочитайте мой ответ на Почему нет строкового вывода с 'echo% var%' после использования 'set var = text' в командной строке? Это имеет большое значение, если первая двойная кавычкаслева от имени переменной или справа от знака равенства при определении переменной среды.См. Также Как установить переменные среды с пробелами?
Давайте посмотрим на этот код:
@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 .По этой причине 2>&1
используется, как документировано Microsoft в статье о с использованием операторов перенаправления команд , чтобы получить выходные данные исполняемого файла, записанного в STDERR , перенаправленного в STDOUT фонаКомандный процесс.
Операторы перенаправления >
и &
должны быть экранированы с помощью символа вставки ^
в FOR , чтобы интерпретировать командную строку как буквенные символы, когда интерпретатор команд Windows обрабатывает этокомандная строка перед выполнением команды FOR , которая выполняет встроенную командную строку в отдельном командном процессе, запущенном в фоновом режиме.
FOR обрабатывает захваченный вывод строка за строкой, пропуская всепустые строки после того, как запущенный исполняемый файл завершен и поэтому запущен cmd.exe
также завершен.
По умолчанию строки, начинающиеся с ;
, также игнорируются FOR , так как точка с запятой является концом строки по умолчаниюперсонаж.eol=
указывается для определения символа конца строки во избежание игнорирования непустой строки.
FOR по умолчанию разбивает строку на подстроки (токены) с использованием обычного пробела и горизонталисимвол табуляции как разделители строк.Такое поведение разделения строк, скорее всего, здесь нежелательно.По этой причине delims=
указывается для пустого списка разделителей, чтобы отключить режим разбиения строк и получить присвоение указанной переменной цикла I
всей непустой строки, которая в настоящее время обрабатывается FOR .
Список опций после for /F
обычно задается с помощью "
one или mor опций "
.Здесь невозможно определить пустой список разделителей и без символа конца строки.Таким образом, указанные параметры не заключены в двойные кавычки.Но в этом случае =
и пробел должны быть экранированы с ^
, чтобы интерпретироваться как литеральные символы, а не как разделители аргументов путем cmd.exe
синтаксического анализа этой командной строки FOR для передачи delims= eol=
в качестве одного аргументастрока в команду FOR .
Таким образом, если исполняемый файл, определенный переменной среды Executable
, выводит только одну непустую строку в ANSI, эта строка присваивается переменной среды Data
.
Но, возможно, исполняемый файл выводит интересующую информацию не в ASCII / ANSI, а в Unicode с кодировкой Little Endian UTF-16 и дополнительно выводит две или более пустых строки, как, например, wmic.exe
.В этом случае должна учитываться ошибка FOR при интерпретации закодированных выходных данных Unicode, которая приводит к удалению переменной окружения Data
после определения с данными, представляющими интерес для FOR неправильная обработка кодированных в UTF-16 пустых строк в конце захваченного вывода Unicode.Подробнее об этой ошибке FOR см. Как исправить неправильное поведение при перезаписи переменных при разборе вывода? Решение, используемое здесь, состоит в том, чтобы выйти из цикла после назначения первой непустой строки переменной средыData
путем перехода к коду под меткой HaveData
.
Для понимания используемых команд и их работы откройте окно командной строки, выполните там следующие команды и полностью прочитайте все отображаемые страницы справки.для каждой команды очень тщательно.
echo /?
for /?
goto /?
pause /?
set /?