Załóżmy, że mam dwa programy o nazwie ProgramA
i ProgramB
. Chcę je uruchomić jednocześnie w interpreterze cmd systemu Windows. Ale chcę StdOut
od ProgramA
podpięty do StdIn
z ProgramB
oraz StdOut
od ProgramB
podpięty do StdIn
z ProgramA
.
Coś takiego
________________ ________________ | | | | | StdIn (== ← === ← == (StdOut | | Program A | | Program B | | | | | | StdOut) == → === → ==) StdIn | | ________________ | | ________________ |
Czy jest na to jakaś komenda - jakiś sposób na osiągnięcie tej funkcjonalności z cmd?
windows
batch-file
redirection
stdout
stdin
DarthRubik
źródło
źródło
Odpowiedzi:
Można to zrobić nie tylko, ale tylko za pomocą pliku wsadowego! :-)
Problem można rozwiązać, używając pliku tymczasowego jako „potoku”. Komunikacja dwukierunkowa wymaga dwóch plików „potokowych”.
Proces A odczytuje stdin z „potoku 1” i zapisuje stdout na „potoku 2”
Proces B odczytuje stdin z „potoku 2” i zapisuje stdout na „potoku 1”
Ważne jest, aby oba pliki istniały przed uruchomieniem któregokolwiek z procesów. Pliki powinny być puste na początku.
Jeśli plik wsadowy próbuje odczytać z pliku, który znajduje się na bieżącym końcu, po prostu nic nie zwraca, a plik pozostaje otwarty. Więc moja procedura readLine ciągle czyta, dopóki nie otrzyma niepustej wartości.
Chcę móc czytać i pisać pusty ciąg, więc moja procedura writeLine dołącza dodatkowy znak, który readLine usuwa.
Mój proces A kontroluje przepływ. Inicjuje rzeczy, pisząc 1 (wiadomość do B), a następnie wchodzi w pętlę z 10 iteracjami, w której odczytuje wartość (wiadomość z B), dodaje 1, a następnie zapisuje wynik (wiadomość do B). W końcu czeka na ostatnią wiadomość z B, a następnie zapisuje wiadomość „wyjdź” do B i kończy działanie.
Mój proces B znajduje się w warunkowo nieskończonej pętli, która odczytuje wartość (wiadomość z A), dodaje 10, a następnie zapisuje wynik (wiadomość do A). Jeśli B kiedykolwiek czyta komunikat „wyjdź”, to natychmiast się kończy.
Chciałem wykazać, że komunikacja jest w pełni synchroniczna, dlatego wprowadzam opóźnienie zarówno w pętlach procesowych A, jak i B.
Zauważ, że procedura readLine znajduje się w ciasnej pętli, która stale nadużywa zarówno procesora, jak i systemu plików, czekając na dane wejściowe. Do pętli można dodać opóźnienie PING, ale wówczas procesy nie będą tak responsywne.
Używam prawdziwej potoku jako wygody do uruchamiania zarówno procesów A, jak i B. Ale rura nie działa, ponieważ nie przechodzi przez nią komunikacja. Cała komunikacja odbywa się za pośrednictwem moich tymczasowych plików „potokowych”.
Równie dobrze mogłem użyć START / B do uruchomienia procesów, ale potem muszę wykryć, kiedy oba kończą się, aby wiedzieć, kiedy należy usunąć tymczasowe pliki „potoku”. Korzystanie z rury jest znacznie prostsze.
Zdecydowałem się umieścić cały kod w jednym pliku - skrypcie głównym, który uruchamia A i B, a także kod A i B. Mogłem użyć osobnego pliku skryptu dla każdego procesu.
test.bat
--WYNIK--
Życie jest trochę łatwiejsze dzięki językowi wyższego poziomu. Poniżej znajduje się przykład, który używa VBScript dla procesów A i B. Nadal używam partii do uruchomienia procesów. Używam bardzo fajnej metody opisanej na stronie Czy można osadzić i uruchomić VBScript w pliku wsadowym bez użycia pliku tymczasowego? aby osadzić wiele skryptów VBS w jednym skrypcie wsadowym.
W języku wyższym, takim jak VBS, możemy użyć zwykłego potoku, aby przekazać informacje z A do B. Potrzebujemy tylko jednego tymczasowego pliku „potoku”, aby przekazać informacje z B z powrotem do A. Ponieważ mamy teraz działający potok, A proces nie musi wysyłać komunikatu „wyjdź” do B. Proces B po prostu zapętla się, aż osiągnie koniec pliku.
Na pewno miło jest mieć dostęp do odpowiedniej funkcji uśpienia w VBS. Pozwala mi to łatwo wprowadzić krótkie opóźnienie w funkcji readLine, aby przerwać procesor.
Jednak w jednym czytaniu jest jedna zmarszczka. Na początku pojawiały się sporadyczne awarie, dopóki nie zdałem sobie sprawy, że czasami readLine wykryje, że informacje są dostępne na standardowym wejściu, i od razu spróbuję odczytać linię, zanim B będzie miał szansę zakończyć pisanie linii. Rozwiązałem problem, wprowadzając krótkie opóźnienie między testem końca pliku a odczytem. Wydawało mi się, że opóźnienie wynoszące 5 ms jest dla mnie wystarczające, ale podwoiłem to do 10 ms, aby być po bezpiecznej stronie. To bardzo interesujące, że partia nie cierpi z powodu tego problemu. Omówiliśmy to krótko (5 krótkich postów) na stronie http://www.dostips.com/forum/viewtopic.php?f=3&t=7078#p47432 .
Dane wyjściowe są takie same jak w przypadku czystego rozwiązania wsadowego, z tym wyjątkiem, że nie ma tam końcowych wierszy „quit”.
źródło
Uwaga: Patrząc wstecz, ponownie czytając pytanie, nie robi to, o co zostanie poproszony. Ponieważ chociaż łączy dwa procesy razem (w interesujący sposób, który działałby nawet w sieci!), Nie łączy obu sposobów.
Mam nadzieję, że uzyskasz kilka odpowiedzi na to pytanie.
Oto moja odpowiedź, ale nie akceptuj jej, poczekaj na inne odpowiedzi, chcę zobaczyć inne odpowiedzi.
Zostało to zrobione z cygwina. I za pomocą polecenia „nc” (sprytnego). „Wc -l” po prostu zlicza linie. Łączę więc dowolne dwa polecenia, w tym przypadku echo i wc, używając nc.
Polecenie po lewej zostało wykonane jako pierwsze.
nc to polecenie, które może a) utworzyć serwer lub b) połączyć się z serwerem jak polecenie telnet w trybie surowym. Używam użycia „a” w lewym poleceniu, a użycie „b” w prawym poleceniu.
Więc nc siedział i nasłuchiwał, czekając na dane wejściowe, a następnie
wc -l
przesyłać dane wejściowe do i zliczać linie i wyprowadzać liczbę wprowadzonych linii.Następnie uruchomiłem wiersz, aby powtórzyć jakiś tekst i wysłać go na adres 127.0.0.1:123, który jest wspomnianym serwerem.
Możesz skopiować polecenie nc.exe z cygwin i spróbować użyć tego pliku cygwin1.dll w tym samym katalogu. Albo możesz to zrobić od samego cygwina, tak jak ja. Nie widzę nc.exe w gnuwin32. Mają wyszukiwanie http://gnuwin32.sourceforge.net/ i nc lub netcat nie pojawia się. Ale możesz uzyskać cygwin https://cygwin.com/install.html
źródło
netstat -aon | find ":123"
zobaczyć, że polecenie po lewej stronie utworzyło serwerwc
tyłu doecho
polecenia).nc -lp9999 | prog1 | prog2 | nc 127.0.0.1 9999
konieczne może być podjęcie kroków w celu zapewnienia, że bufory zostaną opróżnione w odpowiednim czasieJednym z hacków (wolałbym tego nie robić, ale o to teraz chodzi) jest napisanie aplikacji C # , która zrobi to za Ciebie. Nie wdrożyłem niektórych kluczowych funkcji w tym programie (takich jak używanie argumentów podanych mi), ale oto:
Następnie, gdy ten program będzie w pełni funkcjonalny i kod debugowania zostanie usunięty, użyjesz go w następujący sposób:
źródło