Предположим, у меня есть две программы под названием ProgramA
и ProgramB
. Я хочу запустить их обоих одновременно в интерпретаторе Windows cmd. Но я хочу, чтобы StdOut
из ProgramA
зацепили к StdIn
о ProgramB
и StdOut
о ProgramB
зацепили к StdIn
о ProgramA
.
Что-то вроде этого
________________ ________________ | | | | | StdIn (== ← === ← == (StdOut | | Программа А | | Программа Б | | | | | | StdOut) == → === → ==) StdIn | | ________________ | | ________________ |
Есть ли команда, чтобы сделать это - каким-то образом добиться этой функциональности из cmd?
windows
batch-file
redirection
stdout
stdin
DarthRubik
источник
источник
Ответы:
Это можно сделать не только с помощью командного файла! :-)
Проблема может быть решена путем использования временного файла в качестве «канала». Для двунаправленной связи требуются два «конвейерных» файла.
Процесс A читает стандартный ввод из "pipe1" и записывает стандартный вывод в pipe2
Процесс B считывает стандартный ввод из pipe2 и записывает стандартный вывод в pipe1
Важно, чтобы оба файла существовали до запуска любого процесса. Файлы должны быть пустыми в начале.
Если пакетный файл пытается прочитать из файла, который находится на текущем конце, он просто ничего не возвращает, и файл остается открытым. Так что моя подпрограмма readLine постоянно читает, пока не получит непустое значение.
Я хочу иметь возможность читать и писать пустую строку, поэтому моя подпрограмма writeLine добавляет дополнительный символ, который readLine удаляет.
Мой процесс A контролирует поток. Он инициирует вещи, записывая 1 (сообщение в B), а затем входит в цикл с 10 итерациями, где читает значение (сообщение из B), добавляет 1 и затем записывает результат (сообщение в B). Наконец, он ожидает последнего сообщения от B, а затем записывает сообщение «выход» в B и завершает работу.
Мой процесс B находится в условно бесконечном цикле, который читает значение (сообщение от A), добавляет 10, а затем записывает результат (сообщение в A). Если B когда-либо прочитает сообщение «выйти», оно немедленно завершится.
Я хотел продемонстрировать, что связь полностью синхронна, поэтому я ввел задержку в обоих циклах процесса A и B.
Обратите внимание, что процедура readLine находится в узком цикле, который непрерывно использует как процессор, так и файловую систему, ожидая ввода. Задержка PING может быть добавлена к циклу, но тогда процессы не будут такими отзывчивыми.
Я использую настоящий канал для удобства запуска процессов A и B. Но канал не работает, так как через него не проходит никакой связи. Все общение происходит через мои временные "трубочные" файлы.
С тем же успехом я мог бы использовать START / B для запуска процессов, но затем я должен определить, когда они оба завершаются, чтобы я знал, когда удалять временные файлы «канала». Гораздо проще использовать трубу.
Я решил поместить весь код в один файл - главный скрипт, который запускает A и B, а также код для A и B. Я мог бы использовать отдельный файл скрипта для каждого процесса.
test.bat
--ВЫХОД--
Жизнь немного проще с языком высшего уровня. Ниже приведен пример, который использует VBScript для процессов A и B. Я все еще использую пакет для запуска процессов. Я использую очень крутой метод, описанный в разделе Возможно ли встроить и выполнить VBScript в пакетном файле без использования временного файла? встроить несколько VBS-скриптов в один пакетный скрипт.
С более высоким языком, таким как VBS, мы можем использовать обычный канал для передачи информации от A к B. Нам нужен только один временный файл "pipe" для передачи информации от B обратно к A. Поскольку у нас теперь есть работающий канал, A процессу не нужно отправлять сообщение «выход» в B. Процесс B просто зацикливается, пока не достигнет конца файла.
Конечно, приятно иметь доступ к правильной функции сна в VBS. Это позволяет мне легко вводить небольшую задержку в функцию readLine, чтобы дать CPU перерыв.
Однако в readLIne есть одна морщина. Сначала я получал периодические сбои, пока не понял, что иногда readLine обнаруживает информацию, доступную на stdin, и сразу же пытается прочитать строку, прежде чем B сможет закончить писать строку. Я решил проблему, введя небольшую задержку между проверкой конца файла и чтением. Задержка в 5 мсек, казалось, сделала мой трюк, но я удвоил это до 10 мсек, чтобы быть в безопасности. Очень интересно, что партия не страдает этой проблемой. Мы кратко обсудили это (5 коротких сообщений) по адресу http://www.dostips.com/forum/viewtopic.php?f=3&t=7078#p47432 .
Вывод такой же, как и для чистого пакетного решения, за исключением того, что конечных строк "выход" нет.
источник
Примечание. Оглядываясь назад, снова читая вопрос, он не выполняет то, что ему задают. Поскольку, хотя он связывает два процесса вместе (интересным образом, который бы работал даже по сети!), Он не связывает оба пути.
Я надеюсь, что вы получите несколько ответов на это.
Вот мой ответ, но не принимайте его, ждите других ответов, мне очень хотелось бы увидеть другие ответы.
Это было сделано из Cygwin. И используя команду 'nc' (умная). 'Wc -l' просто считает строки. Так что я связываю любые две команды, в данном случае, echo и wc, используя nc.
Команда слева была сделана первой.
nc - это команда, которая может a) создать сервер или b) подключиться, как команда telnet в режиме raw, к серверу. Я использую использование 'a' в левой команде и использование 'b' в правой команде.
Таким образом, nc сидел и слушал, ожидая ввода, а затем направил бы этот ввод
wc -l
и посчитал количество строк и вывел число введенных строк.Затем я запустил строку, чтобы отразить некоторый текст и отправить этот raw на 127.0.0.1:123, который является упомянутым сервером.
Вы можете скопировать команду nc.exe из cygwin и попробовать использовать ее и нужный файл cygwin1.dll в той же директории. Или вы можете сделать это из самого Cygwin, как я. Я не вижу nc.exe в gnuwin32. У них есть поиск http://gnuwin32.sourceforge.net/ и nc или netcat не подходят. Но вы можете получить Cygwin https://cygwin.com/install.html
источник
netstat -aon | find ":123"
чтобы увидеть, что команда слева создала серверwc
спины кecho
команде).nc -lp9999 | prog1 | prog2 | nc 127.0.0.1 9999
возможно, потребуется предпринять шаги для своевременногоОдин из способов (я бы предпочел не делать этого, но сейчас я собираюсь сделать это) - написать приложение на C #, которое сделает это за вас. Я не реализовал некоторые ключевые функции в этой программе (например, фактически использовал предоставленные мне аргументы), но вот он:
Затем, в конце концов, когда эта программа будет полностью функциональной и код отладки будет удален, вы будете использовать его примерно так:
источник