пакетный файл: установка переменной для возвращаемого значения из вызова функции - PullRequest
0 голосов
/ 25 мая 2019

Что я здесь не так делаю, пожалуйста? Я хочу сделать Windows batch file, которая будет вызывать exe, передавая некоторые аргументы и присваивая возвращаемое значение переменной. Я перепробовал много разных вариантов, но не могу заставить его работать.

SET EXE="path\to\exe"
SET TARGET_FILE="path\to\file\to\be\read\by\exe"

for /f %%i in (%EXE% -arg1 %TARGET_FILE%) do set VAR=%%i

ECHO %VAR%
PAUSE

Чего мне не хватает? В случае, если это имеет значение, два пути выше, вероятно, будут содержать пробелы, строка C:\Program Files\etc.

Ответы [ 2 ]

1 голос
/ 25 мая 2019

Во-первых, пожалуйста, прочитайте мой ответ на Почему нет строкового вывода с '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 /?
1 голос
/ 25 мая 2019

Следующий пакетный файл должен работать. Я не проверял, дайте мне знать, если это не так.

SET EXE="path\to\exe"
SET TARGET_FILE="path\to\file\to\be\read\by\exe"

for /f "delims=" %%i in ('"%EXE% -arg1 %TARGET_FILE%"') do (
echo %%i
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...