1265 Stimmen

Wie man Shell-Befehle aus Ruby aufruft

Wie kann ich Shell-Befehle aus einem Ruby-Programm heraus aufrufen? Wie bekomme ich dann die Ausgabe dieser Befehle zurück in Ruby?

4 Stimmen

Diese Frage ist zwar nützlich, aber sie wird nicht gut gestellt. Ruby hat viele Möglichkeiten, Sub-Shells aufzurufen, die gut dokumentiert sind und leicht durch Lesen der Kernel y Öffnen3 Dokumentation und Suche hier auf SO.

3 Stimmen

Leider ist dieses Thema sehr komplex. Open3 ( docs ) ist die beste Wahl für die meisten Situationen, IMO, aber auf älteren Versionen von Ruby, wird es nicht respektieren eine modifizierte PATH ( bugs.ruby-lang.org/issues/8004 ), und je nachdem, wie Sie args übergeben (insbesondere, wenn Sie opts hash mit Nicht-Schlüsselwörtern verwenden), kann es zu einem Bruch kommen. Aber, wenn Sie diese Situationen treffen, dann tun Sie etwas ziemlich fortgeschritten und Sie können herausfinden, was zu tun ist, indem Sie die Implementierung von Open3 .

6 Stimmen

Ich bin überrascht, dass niemand erwähnt hat Shellwords.escape ( doc ). Sie möchten keine Benutzereingaben direkt in Shell-Befehle einfügen - geben Sie sie zuerst in einer Escape-Funktion ein! Siehe auch Befehlsinjektion .

32voto

Nick Brosnahan Punkte 1271

Bei der Wahl zwischen diesen Mechanismen sind einige Dinge zu bedenken:

  1. Wollen Sie nur stdout oder wollen Sie auch stderr benötigen? Oder sogar herausgetrennt?
  2. Wie groß ist Ihr Output? Wollen Sie das gesamte Ergebnis im Speicher halten?
  3. Möchten Sie einige Ihrer Ausgabe lesen, während der Unterprozess noch läuft?
  4. Benötigen Sie Ergebniscodes?
  5. Benötigen Sie ein Ruby-Objekt, das den Prozess repräsentiert und mit dem Sie bei Bedarf beenden kann?

Sie können alles von einfachen Backticks (``) benötigen, system() y IO.popen zu einer ausgewachsenen Kernel.fork / Kernel.exec con IO.pipe y IO.select .

Sie können auch Timeouts einbauen, wenn ein Unterprozess zu lange für die Ausführung braucht.

Leider ist es sehr viel hängt .

29voto

Steve Willard Punkte 16337

Ich bin definitiv kein Ruby-Experte, aber ich werde es versuchen:

$ irb 
system "echo Hi"
Hi
=> true

Sie sollten auch in der Lage sein, Dinge zu tun wie:

cmd = 'ls'
system(cmd)

28voto

j-g-faustus Punkte 8433

Eine weitere Möglichkeit:

Wenn Sie:

  • sowohl stderr als auch stdout benötigen
  • kann/will Open3/Open4 nicht verwenden (sie lösen in NetBeans auf meinem Mac Ausnahmen aus, keine Ahnung warum)

Sie können die Shell-Umleitung verwenden:

puts %x[cat bogus.txt].inspect
  => ""

puts %x[cat bogus.txt 2>&1].inspect
  => "cat: bogus.txt: No such file or directory\n"

El 2>&1 Syntax funktioniert über Linux , Mac und Windows seit den frühen Tagen von MS-DOS.

25voto

Utensil Punkte 14584

Die obigen Antworten sind bereits sehr gut, aber ich möchte den folgenden zusammenfassenden Artikel unbedingt teilen: " 6 Möglichkeiten, Shell-Befehle in Ruby auszuführen "

Im Grunde sagt sie uns das:

Kernel#exec :

exec 'echo "hello $HOSTNAME"'

system y $? :

system 'false' 
puts $?

Backticks (`):

today = `date`

IO#popen :

IO.popen("date") { |f| puts f.gets }

Open3#popen3 -- stdlib:

require "open3"
stdin, stdout, stderr = Open3.popen3('dc') 

Open4#popen4 -- ein Juwel:

require "open4" 
pid, stdin, stdout, stderr = Open4::popen4 "false" # => [26327, #<IO:0x6dff24>, #<IO:0x6dfee8>, #<IO:0x6dfe84>]

18voto

dragon788 Punkte 3063

Wenn Sie Bash wirklich brauchen, beachten Sie den Hinweis in der "besten" Antwort.

Zunächst ist zu beachten, dass Ruby bei Aufrufen einer Shell typischerweise /bin/sh , no Bash. Einige Bash-Syntaxen werden nicht unterstützt von /bin/sh auf allen Systemen.

Wenn Sie die Bash verwenden müssen, fügen Sie bash -c "your Bash-only command" innerhalb der von Ihnen gewünschten Aufrufmethode:

quick_output = system("ls -la")

quick_bash = system("bash -c 'ls -la'")

Zum Testen:

system("echo $SHELL")
system('bash -c "echo $SHELL"')

Oder wenn Sie eine bestehende Skriptdatei ausführen wie

script_output = system("./my_script.sh")

Rubinrot debe die ganze Sache zu würdigen, aber Sie können auch

system("bash ./my_script.sh")

um sicher zu gehen, obwohl es einen leichten Mehraufwand durch /bin/sh läuft /bin/bash werden Sie es wahrscheinlich nicht bemerken.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X