Я видел много ответов на этот вопрос с использованием цикла for для записи вывода программы построчно в переменную. Это в значительной степени именно то, что мне нужно, НО, насколько я понимаю, это зависит от завершения программы, а затем от возможности перебирать известное количество строк.
Мой случай таков: у меня есть программа "example.exe", которая не завершается сама по себе, а постоянно выводит строки данных. Я буду запускать эту программу из пакетного сценария с несколькими аргументами, и я хочу, чтобы строки этой программы заканчивались переменной "LINE", чтобы всякий раз, когда появляется новый вывод этой программы, я хотел, чтобы "LINE" обновлялась и запустите несколько дополнительных строк кода, делающих что-то с новой переменной set.
в псевдокоде:
Set LINE=*example.exe output*
echo %LINE%
... some more operations on LINE
Как я могу добиться этого без необходимости завершать "example.exe" и, желательно, без необходимости передавать все в файл и затем считывать из этого файла?
Ответ 1 · рейтинг 2 · dbenham
Если вы ограничиваете себя собственными пакетными командами, то любой ответ потребует чтения ввода с помощью SET /P, который имеет ограничение в 1021 байт на строку. Если ваш вывод превышает 1021 байт на строку, то это невозможно с чистым пакетом.
Выполнить задачу несложно, если исполняемая программа записывает в конце какую-то уникальную строку, означающую, что она завершена.
Для этой демонстрации я заменю исполняемый файл небольшим пакетным скриптом. Пакетный сценарий (программа:sender) будет просто повторять любой введенный вами ввод и завершится, когда вы нажмете QUIT.
Подпрограмма :receiver будет читать и обрабатывать строки, пока не получит QUIT.
Я просто передаю вывод :sender в :receiver :-)
@echo off
setlocal enableDelayedExpansion
if "%~1" == ":sender" goto :sender
if "%~1" == ":receiver" goto :receiver
"%~f0" :sender | "%~f0" :receiver
exit /b
:sender
set "str="
set /p "str=>" >&2
echo(!str!
if !str! neq QUIT goto :sender
exit /b
:receiver
set "LINE="
set /p "LINE="
echo LINE=!LINE!
REM do whatever...
if !LINE! neq QUIT goto :receiver
exit /b
-- ОБРАЗЕЦ В/В --
>Hello world!
LINE=Hello world!
> This is a test
LINE= This is a test
>
LINE=
>Almost done
LINE=Almost done
>QUIT
LINE=QUIT
Для вашего использования вы просто замените свой exe-файл на :sender в канале
yourProgram.exe | "%~f0" :receiver
Если ваш исполняемый файл действительно работает "навсегда", вы можете отключить логику QUIT. Но тогда я полагаю, что вам придется убить вашу консоль, когда вы будете готовы завершить работу - Ctrl+C не сработает, чтобы убить :receiver.
Ситуация усложняется, если вы хотите автоматически обнаруживать и завершать канал, когда больше нет входных данных, не полагаясь на уникальную строку завершения. Решение очень похоже на мою реализацию пакетной программы. Я оставлю вам возможность адаптировать batchTee.bat к вашей ситуации :-)