Angenommen, ich habe zwei Programme namens ProgramA
und ProgramB
. Ich möchte beide gleichzeitig im Windows-Cmd-Interpreter ausführen. Aber ich möchte das StdOut
von ProgramA
süchtig nach dem StdIn
von ProgramB
und das StdOut
von ProgramB
süchtig nach dem StdIn
von ProgramA
.
Etwas wie das
________________ ________________ | | | | | StdIn (== ← === ← == (StdOut | | Programm A | | Programm B | | | | | | StdOut) == → === → ==) StdIn | | ________________ | | ________________ |
Gibt es einen Befehl, um dies zu tun - eine Möglichkeit, diese Funktionalität von cmd aus zu erreichen?
windows
batch-file
redirection
stdout
stdin
DarthRubik
quelle
quelle
Antworten:
Dies ist nicht nur möglich, sondern auch nur mit einer Batch-Datei! :-)
Das Problem kann gelöst werden, indem eine temporäre Datei als "Pipe" verwendet wird. Für die bidirektionale Kommunikation sind zwei "Pipe" -Dateien erforderlich.
Prozess A liest stdin von "pipe1" und schreibt stdout in "pipe2".
Prozess B liest stdin von "pipe2" und schreibt stdout in "pipe1".
Es ist wichtig, dass beide Dateien vorhanden sind, bevor Sie einen der beiden Prozesse starten. Die Dateien sollten zu Beginn leer sein.
Wenn eine Batchdatei versucht, aus einer Datei zu lesen, die sich gerade am aktuellen Ende befindet, wird einfach nichts zurückgegeben, und die Datei bleibt geöffnet. Meine readLine-Routine liest also kontinuierlich, bis sie einen nicht leeren Wert erhält.
Ich möchte in der Lage sein, eine leere Zeichenfolge zu lesen und zu schreiben, daher hängt meine writeLine-Routine ein zusätzliches Zeichen an, das die readLine entfernt.
Mein A-Prozess steuert den Fluss. Es initiiert Dinge durch Schreiben von 1 (Nachricht an B) und tritt dann in eine Schleife mit 10 Iterationen ein, in der es einen Wert liest (Nachricht von B), 1 addiert und dann das Ergebnis schreibt (Nachricht an B). Schließlich wartet es auf die letzte Nachricht von B und schreibt dann eine "Beenden" -Nachricht an B und wird beendet.
Mein B-Prozess befindet sich in einer bedingten Endlosschleife, die einen Wert liest (Nachricht von A), 10 addiert und dann das Ergebnis schreibt (Nachricht an A). Wenn B jemals eine "Beenden" -Nachricht liest, wird sie sofort beendet.
Ich wollte zeigen, dass die Kommunikation vollständig synchron ist, daher füge ich eine Verzögerung sowohl in der A- als auch in der B-Prozessschleife ein.
Beachten Sie, dass sich die readLine-Prozedur in einer engen Schleife befindet, die sowohl die CPU als auch das Dateisystem kontinuierlich missbraucht, während sie auf die Eingabe wartet. Der Schleife könnte eine PING-Verzögerung hinzugefügt werden, aber dann reagieren die Prozesse nicht so schnell.
Ich verwende eine echte Pipe, um sowohl den A- als auch den B-Prozess zu starten. Die Pipe ist jedoch nicht funktionsfähig, da keine Kommunikation durch sie geleitet wird. Die gesamte Kommunikation erfolgt über meine temporären "Pipe" -Dateien.
Ich hätte genauso gut START / B verwenden können, um die Prozesse zu starten, aber dann muss ich erkennen, wann beide beendet werden, damit ich weiß, wann die temporären "Pipe" -Dateien gelöscht werden müssen. Es ist viel einfacher, das Rohr zu benutzen.
Ich habe mich dafür entschieden, den gesamten Code in eine einzige Datei zu packen - das Masterskript, mit dem A und B gestartet werden, sowie den Code für A und B. Ich hätte für jeden Prozess eine separate Skriptdatei verwenden können.
test.bat
--AUSGABE--
Mit einer höheren Sprache ist das Leben ein bisschen einfacher. Unten finden Sie ein Beispiel, das VBScript für die Prozesse A und B verwendet. Ich benutze immer noch Batch, um die Prozesse zu starten. Ich verwende eine sehr coole Methode, die unter Ist es möglich, VBScript in eine Batchdatei einzubetten und auszuführen, ohne eine temporäre Datei zu verwenden? um mehrere VBS-Skripte in ein einziges Batch-Skript einzubetten.
Mit einer höheren Sprache wie VBS können wir eine normale Pipe verwenden, um Informationen von A nach B zu übergeben. Wir benötigen nur eine einzige temporäre "Pipe" -Datei, um Informationen von B zurück nach A zu übergeben. Da wir jetzt eine funktionierende Pipe haben, die A. Der Prozess muss keine "Beenden" -Nachricht an B senden. Der B-Prozess wird einfach wiederholt, bis das Dateiende erreicht ist.
Es ist sicher schön, Zugang zu einer richtigen Schlaffunktion in VBS zu haben. Dadurch kann ich leicht eine kurze Verzögerung in die readLine-Funktion einführen, um der CPU eine Pause zu geben.
Es gibt jedoch eine Falte in readLIne. Zuerst bekam ich zeitweise Fehler, bis mir klar wurde, dass readLine manchmal feststellte, dass Informationen auf stdin verfügbar sind, und sofort versuchte, die Zeile zu lesen, bevor B die Möglichkeit hatte, das Schreiben der Zeile abzuschließen. Ich habe das Problem gelöst, indem ich eine kurze Verzögerung zwischen dem Dateiende-Test und dem Lesen eingeführt habe. Eine Verzögerung von 5 ms schien den Trick für mich zu tun, aber ich habe das auf 10 ms verdoppelt, nur um auf der sicheren Seite zu sein. Es ist sehr interessant, dass bei Batch dieses Problem nicht auftritt. Wir haben dies kurz besprochen (5 kurze Beiträge) unter http://www.dostips.com/forum/viewtopic.php?f=3&t=7078#p47432 .
Die Ausgabe ist die gleiche wie bei der reinen Batch-Lösung, außer dass die letzten "Quit" -Zeilen nicht vorhanden sind.
quelle
Hinweis: Wenn Sie die Frage im Nachhinein noch einmal lesen, wird nicht das getan, was gefragt wird. Da es zwar zwei Prozesse miteinander verbindet (auf eine interessante Weise, die sogar über ein Netzwerk funktionieren würde!), Verknüpft es jedoch nicht beide Wege.
Ich hoffe du bekommst ein paar Antworten darauf.
Hier ist meine Antwort, aber akzeptiere sie nicht. Warte auf andere Antworten. Ich bin gespannt auf andere Antworten.
Dies wurde von Cygwin gemacht. Und mit dem Befehl 'nc' (dem klugen). Das 'wc -l' zählt nur Zeilen. Also verknüpfe ich zwei beliebige Befehle, in diesem Fall echo und wc, mit nc.
Der Befehl links wurde zuerst ausgeführt.
nc ist ein Befehl, der a) einen Server erstellen oder b) wie der Telnet-Befehl im Raw-Modus eine Verbindung zu einem Server herstellen kann. Ich verwende die Verwendung 'a' im linken Befehl und die Verwendung 'b' im rechten Befehl.
Also saß nc da und lauschte auf eine Eingabe und leitete diese Eingabe an
wc -l
die Zeilen weiter, zählte sie und gab die Anzahl der eingegebenen Zeilen aus.Ich habe dann die Zeile ausgeführt, um einen Text wiederzugeben und diesen Rohdaten an 127.0.0.1:123 zu senden, den genannten Server.
Sie können den Befehl nc.exe von cygwin kopieren und versuchen, diesen und die benötigte Datei cygwin1.dll im selben Verzeichnis zu verwenden. Oder Sie könnten es von Cygwin selbst tun, wie ich es getan habe. Ich sehe nc.exe nicht in gnuwin32. Sie haben eine Suche http://gnuwin32.sourceforge.net/ und nc oder netcat wird nicht angezeigt. Sie können jedoch cygwin https://cygwin.com/install.html herunterladen
quelle
netstat -aon | find ":123"
sehen, dass der Befehl auf der linken Seite den Server erstellt hatwc
hinten zumecho
Befehl).nc -lp9999 | prog1 | prog2 | nc 127.0.0.1 9999
Möglicherweise müssen Schritte unternommen werden, um sicherzustellen, dass die Puffer rechtzeitigEin Hack (ich würde es vorziehen, dies nicht zu tun, aber das ist, was ich jetzt mache ) ist, eine C # -Anwendung zu schreiben , um dies für Sie zu tun. Ich habe einige wichtige Funktionen in diesem Programm nicht implementiert (z. B. die Verwendung der mir gegebenen Argumente), aber hier ist es:
Wenn dieses Programm dann voll funktionsfähig ist und der Debug-Code entfernt wurde, würden Sie es ungefähr so verwenden:
quelle