Wenn man einen externen Befehl in Ruby ausführen möchte…
…wie wkhtmltopdf, um eine HTML-Datei in ein PDF zu konvertieren.
Es gibt einige Ruby-Methoden, die man verwenden kann.
Abhängig von der Methode, die man verwendet, erhält man unterschiedliche Ergebnisse.
Lassen Sie uns diese Methoden gemeinsam erforschen!
Die Ruby-System-Methode
Die Ruby-System-Methode ist der einfachste Weg, einen externen Befehl auszuführen.
Sie sieht so aus:
system("ls")
Beachten Sie, dass system
die Befehlsausgabe ausgibt, sobald sie erfolgt.
Außerdem lässt das System dein Ruby-Programm warten, bis der Befehl ausgeführt wurde:
Versuch dies:
system("sleep 2")
Es gibt Möglichkeiten, Befehle im Hintergrund auszuführen, wie wir später sehen werden.
Das System kann 3 mögliche Werte zurückgeben:
-
true
wenn der Befehl funktioniert hat -
false
wenn der Befehl einen Fehlercode zurückgibt -
nil
wenn die Befehlsausführung fehlschlägt (Befehl nicht gefunden)
Den Exit-Statuscode des letzten externen Befehls, den Sie ausgeführt haben, können Sie mit der globalen Variable $?
abrufen. Dieser Statuscode kann Ihnen mehr Informationen darüber geben, warum der Befehl fehlgeschlagen ist.
Was ist eine Shell-Erweiterung?
Wenn Sie einen externen Befehl mit system
ausführen, erhalten Sie den Effekt der „Shell-Erweiterung“.
Shell-Erweiterung bedeutet, dass die Shell (sh/bash/zsh) einige Sonderzeichen (*
, ?
und ")# "best"
This will not change the current environment of your Ruby application.
%x / Kernel#`
If you want to get the output from the command you're running, instead of displaying it then you can use %x
oder die Kernel#`
-Methode) verwendet.
Sie tun dasselbe.
Hier ist ein Beispiel:
`ls`
Ein anderes mit %x
:
%x|ls|
Diese beiden Beispiele geben eine Zeichenkette mit der Ausgabe des ls
-Befehls zurück.
Beachte, dass du immer noch warten musst, bis der Befehl beendet ist, wenn du ihn nicht innerhalb eines Threads ausführst.
Fork + Exec verwenden, um externe Befehle in einem separaten Prozess auszuführen
Forking erstellt eine Kopie des aktuellen Prozesses (der Ruby-Anwendung), die dann mit exec durch einen anderen Prozess ersetzt werden kann.
Hinweis: Die Fork-Methode ist unter Windows nicht verfügbar.
Dies ist ein beliebtes Muster in der Unix-Welt.
So funktioniert es:
fork { exec("ls") }
Dies führt ls
in einem anderen Prozess aus & und zeigt dessen Ausgabe an.
Da dieser Befehl in einem anderen Prozess ausgeführt wird, blockiert er nicht die Ausführung deiner Ruby-Anwendung wie die Methode system
oder %x
.
Wichtig:
Wenn du exec
ohne fork
verwendest, wird dein aktueller Prozess ersetzt.
Das bedeutet, dass dein Ruby-Programm beendet wird.
Wie man die Popen-Methode für die Zwei-Wege-Kommunikation mit einem externen Programm verwendet
Wenn du:
- Mehr Kontrolle über den Prozess
- Zwei-Wege-Kommunikation
dann ist die IO.popen
-Methode das, wonach du suchst.
Im folgenden Beispiel verwende ich die popen-Methode, um einen irb
Prozess zu starten, dann einige Eingaben an ihn zu senden & und die Ausgaben zu lesen.
Hier das Beispiel:
r = IO.popen("irb", "r+")r.write "puts 123 + 1\n"3.times { puts r.gets }r.write "exit\n"
Diese r
Variable ist ein IO-Objekt, das bedeutet, dass man schreiben & und von ihr lesen kann wie von einer normalen Datei.
Die Verwendung von popen
bedeutet auch, dass Ihr externer Befehl in einem eigenen Prozess ausgeführt wird, so dass Sie ihn nicht in einem Thread ausführen müssen.
Es gibt auch eine popen3
Methode in der Standardbibliothek.
Der Unterschied zum regulären popen
besteht darin, dass es reguläre Ausgabe-& Fehlermeldungen in separate IO-Objekte aufteilt.
Abschluss
Sie haben die verschiedenen Möglichkeiten kennengelernt, wie Sie mit externen Befehlen in Ruby interagieren können.
Seien Sie vorsichtig damit!
Übergeben Sie keine Benutzereingaben an diese Befehle, es sei denn, Sie wollen ein Sicherheitsproblem in Ihrer Ruby-Anwendung.