Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как записать вывод все еще работающей программы в переменную в пакетном файле Windows 10

Автор вопроса: JeffreyОтветов: 1

Я видел много ответов на этот вопрос с использованием цикла for для записи вывода программы построчно в переменную. Это в значительной степени именно то, что мне нужно, НО, насколько я понимаю, это зависит от завершения программы, а затем от возможности перебирать известное количество строк.

Мой случай таков: у меня есть программа "example.exe", которая не завершается сама по себе, а постоянно выводит строки данных. Я буду запускать эту программу из пакетного сценария с несколькими аргументами, и я хочу, чтобы строки этой программы заканчивались переменной "LINE", чтобы всякий раз, когда появляется новый вывод этой программы, я хотел, чтобы "LINE" обновлялась и запустите несколько дополнительных строк кода, делающих что-то с новой переменной set.

в псевдокоде:

Set LINE=*example.exe output*
echo %LINE%
... some more operations on LINE

Как я могу добиться этого без необходимости завершать "example.exe" и, желательно, без необходимости передавать все в файл и затем считывать из этого файла?

  • связано Stephan 24.03.2018

windows-10batch-filevariable-assignment

Ответы

Ответ 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 к вашей ситуации :-)

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы