** "Sieht aus wie JavaScript, Gehirn (Inhalt) ist Ruby, (Stabilität ist AC / DC)" ** Skriptsprache Kinx ). Die Sprache ist die Bibliothek. Also, wie man die Bibliothek benutzt.
Diese Zeit ist Prozess. Ich habe es eilig gemacht, weil es notwendig war, einen Kinderprozess zu starten.
System.exec()
Eine Befehlsausführungsschnittstelle, die seit langem als Standard vorbereitet ist. Es ist einfach, weil es einfach "system ()" auf der C-Ebene aufruft, aber es ist unpraktisch, weil es nicht zurückkommt, bis es fertig ist, oder weil es nicht die Standardausgabe erhalten kann. Da der Befehl jedoch über die Shell ausgeführt wird, können Weiterleitungen verwendet werden.
Also habe ich dieses Mal eine "Prozess" -Klasse erstellt, die mehr kann, und das ist der Favorit in dieser Erklärung.
Process
using Process
Die Prozessbibliothek ist nicht integriert. Verwenden Sie daher die using-Direktive, um sie explizit zu laden.
using Process;
Exec
Das Process-Objekt wird mit new Process (Befehl, Optionen)
erstellt. Das Argument ist ein Befehlsname und ein Array von Argumenten oder eine Befehlszeichenfolge. Im Fall eines Arrays scheint es, als würden die Argumente separat übergeben, und im Fall einer Befehlszeilenzeichenfolge wird sie intern analysiert und automatisch in ein Array-Format zerlegt.
Das erstellte Prozessobjekt verfügt über die folgenden Methoden.
Methode | Überblick |
---|---|
run() |
Starten Sie den Prozess. |
launch() |
Starten Sie den Prozess und trennen Sie die Verbindung. |
std() |
Die als Argumente übergebenen Optionen werden zurückgegeben.{ in: opts.in, out: opts.out, err: opts.err } |
Zu diesem Zeitpunkt noch nicht ausgeführt. Es startet, wenn "run ()" oder "launch ()" ausgeführt wird. run ()
gibt ein Objekt der Klasse ProcessController
zurück.
Run
run ()
gibt ein Objekt der Klasse ProcessController
zurück.
var p = new Process(["cmd","arg1"]).run();
Launch
launch ()
gibt nichts zurück (oder eher null). Die Methode besteht darin, sich nach dem Herausschieben nicht um das Kind zu kümmern.
new Process(["cmd","arg1"]).launch();
ProcessController
Die von "run ()" zurückgegebene "ProcessController" -Klasse verfügt über die folgenden Methoden.
Methode | Überblick |
---|---|
isAlive() |
True, wenn der Prozess aktiv ist, wenn er bereits beendet wurde, oderdetach Falsch, nachdem Sie fertig sind |
wait() |
Wartet auf das Ende des Prozesses und gibt nach dem Ende den Endcode des Prozesses zurück.detach Dann wird 0 zurückgegeben. |
detach() |
Trennen Sie den Prozess |
remove ()
wird nach dem Start des Prozesses getrennt. Unter Linux unterscheidet sich der Vorgang geringfügig vom Fall des Trennens mit "launch ()", aber Sie möchten dasselbe tun. Der interne Vorgang ist unter Windows identisch.
Unter Linux wird die sogenannte ** Double-Fork ** -Methode verwendet, um die Verbindung zu trennen, wenn der Prozess gestartet wird. Dies kann jedoch nur verwendet werden, wenn der Prozess gestartet wird. Es ist praktisch unmöglich, die Verbindung nach dem Starten eines Prozesses zu trennen, und wenn der übergeordnete Prozess nicht richtig "wartet" oder "wartet", überlebt das Kind als Zombie.
Im Moment von remove ()
starte ich einen Thread nur für waitpid
und kümmere mich darum, bis das Kind stirbt.
Double-Fork ist übrigens Linux,
Mit der Funktion ... können Sie den Prozess nach dem Verzweigen verzweigen, dann den ersten gegabelten Prozess in Eile beenden und init den Enkelprozess verwalten lassen.
Der oberste übergeordnete Prozess merkt sich die Wartezeit des ersten gegabelten Kindes. Mein Enkel ist derjenige, der sich um mich kümmert.
Wait
Das Folgende ist ein Beispiel für das Warten auf das Ende und das Abrufen des Endcodes.
var p = new Process(["cmd", "arg1"]).run();
var status = p.wait();
Wenn Sie "Trennen" haben, können Sie es natürlich nicht bekommen (0 wird zurückgegeben).
Detach
Das "Ablösen", das früher herauskam. Der Prozess kann auch "trennen" sein. Wenn Sie es trennen, wird die Verbindung mit dem Kind unterbrochen. Sie müssen nicht warten und sich keine Sorgen um das Ende machen. Oder besser gesagt, Sie können es nicht tun, selbst wenn Sie sich darüber Sorgen machen möchten.
var p = new Process(["cmd", "arg1"]).run();
p.detach();
Pipe
Ich warte auf die Pfeife. Der Hauptzweck der Erstellung von "Prozess" ist die Pipe. Die am meisten gewünschte Funktion besteht darin, die Standardeingabe / -ausgabe mit dem untergeordneten Prozess frei mit einer Pipe zu verbinden, um Informationen auszutauschen.
Die Pipe wird durch "opts" von "new Process (cmd, opts)" angegeben. Es gibt drei Arten von Parametern:
Parameter | Inhalt |
---|---|
in |
Geben Sie die Standardeingabe an. Sie können ein Pipe-Objekt, eine Zeichenfolge, $stdin |
out |
Geben Sie die Standardausgabe an. Sie können ein Pipe-Objekt, eine Zeichenfolge, $stdout Oder$stderr |
err |
Geben Sie die Standardfehlerausgabe an. Sie können ein Pipe-Objekt, eine Zeichenfolge, $stdout Oder$stderr |
$ stdin
, $ stdout
, $ stderr
... Binden Sie die Eingabequelle und das Ausgabeziel an die Standardeingabe / -ausgabe dieses Prozesses.Pipe-Objekte werden mit new Pipe ()
erstellt. Gibt ein Array von zwei Objekten, "[Lesen, Schreiben]", paarweise zurück. Das Pipe-Objekt verfügt über die folgenden Methoden.
Normalerweise wird die "Write" -Pipe als "out" oder "err" des untergeordneten Prozesses angegeben und aus der "Read" -Pipe gelesen.
Read Pipe
Schließen Sie das Rohr nach run ()
. Weil es gesetzt ist, wenn run ()
fertig ist.
Methode | |
---|---|
peek() |
Gibt 0 zurück, wenn keine Daten in der Pipe vorhanden sind, größer als 0, wenn vorhanden.-1 ist ein Fehler. |
read() |
Holen Sie sich alle Pipe-Daten als String. Wenn keine Daten vorhanden sind, wird eine leere Zeichenfolge zurückgegeben. |
close() |
Schließen Sie das Rohr. |
Write Pipe
Schließen Sie das Rohr nach run ()
. Weil es gesetzt ist, wenn run ()
fertig ist.
Methode | |
---|---|
write(data) |
Schreiben Sie Daten in die Pipe. Es können nicht alle geschrieben werden, und die Anzahl der geschriebenen Bytes wird zurückgegeben. |
close() |
Schließen Sie das Rohr. |
Die allgemeine Form wird wie folgt verwendet.
using Process;
var [r1, w1] = new Pipe();
var p1 = new Process([ "ls", "-1" ], { out: w1 }).run();
w1.close(); //Ich benutze es nicht mehr, damit du es schließen kannst
while (p1.isAlive() || r1.peek() > 0) {
var buf = r1.read();
if (buf.length() < 0) {
System.println("Error...");
return -1;
} else if (buf.length() > 0) {
System.print(buf);
} else {
// System.println("no input...");
}
}
System.println("");
Wenn Sie Write Pipe auf der übergeordneten Prozessseite verwenden, sieht es so aus.
using Process;
//stdin liest von der Pipe und gibt die Standardausgabe aus
[r1, w1] = new Pipe();
var p1 = new Process("cat", { in: r1, out: $stdout }).run();
r1.close(); //Ich benutze es nicht mehr, damit du es schließen kannst
//Senden Sie an stdin auf p1
var nwrite = w1.write("Message\n");
w1.close(); //Rohr schließen, Getriebeende
p1.wait();
Auf diese Weise können Sie übrigens die Standardausgabe und die Standardfehlerausgabe steuern.
new Process("cmd", { out: $stdout, err: $stdout }); //Standardfehlerausgabe mit Standardausgabe zusammenführen
new Process("cmd", { out: $stderr, err: $stderr }); //Standardausgabe mit Standardfehlerausgabe zusammenführen
new Process("cmd", { out: $stderr, err: $stdout }); //Tauschen
Pipeline
Das Anschließen von Rohren ist eine ziemlich mühsame Aufgabe (oder besser gesagt, welche ist ...?). Deshalb habe ich auch "Process.pipeline" definiert, was alles auf einmal erledigt. Zum Schluss setzen Sie eine Rückruffunktion und verwenden Sie sie wie folgt.
var r = Process.pipeline(cmd1, cmd2, cmd3, ..., &(i, o, pipeline) => {
// i ...Schreiben Sie die Pipe für den ersten Befehl an stdin
// o ...Lesen Sie die Pipe aus dem Standard des letzten Befehls
// pipeline ...Pipeline-Objekt
// pipeline.input .......Gleich wie ich oben
// pipeline.output ......Gleich wie oben
// pipeline.peek() ...... pipeline.output.peek()Gleich wie
// pipeline.read() ...... pipeline.output.read()Gleich wie
// pipeline.write() ..... pipeline.input.write()Gleich wie
// pipeline.isAlive() ...True, wenn ein Prozess in der Pipeline aktiv ist
// pipeline.wait() ......Warten Sie, bis alle Prozesse in der Pipeline abgeschlossen sind.
//Gibt den Endcode als Array zurück
//Der Rückgabewert des Rückrufs bleibt unverändert.pipeline()Es wird der Rückgabewert von.
return pipeline.wait();
});
Sie können es verwenden, ohne zurückzurufen.
var pipeline = Process.pipeline(cmd1, cmd2, cmd3, ...);
// pipeline ...Pipeline-Objekt
//Unten weggelassen.
Die untergeordnete Prozessbeziehung unterscheidet sich zwischen Windows und Linux. Daher ist es ein guter Punkt des Skripts, solche Dinge auf einheitliche Weise behandeln zu können. Die Befehle selbst sind jedoch unterschiedlich, so dass es schwierig ist, sie zu absorbieren. Ich bin ein Windows-Benutzer, verwende jedoch UnxUtils, um einige Unix-Befehle auch an der Eingabeaufforderung verfügbar zu machen. (Ich mag Cygwin nicht wirklich, weil es die Umgebung verändert ...)
Also nächstes Mal.