Wie rufe ich einen Systembefehl in Rust auf und erfasse seine Ausgabe?


89

Gibt es eine Möglichkeit, einen Systembefehl wie lsoder fuserin Rust aufzurufen ? Wie wäre es mit der Erfassung der Ausgabe?

Antworten:


117

std::process::Command ermöglicht das.

Es gibt mehrere Möglichkeiten, einen untergeordneten Prozess zu erzeugen und einen beliebigen Befehl auf dem Computer auszuführen:

  • spawn - führt das Programm aus und gibt einen Wert mit Details zurück
  • output - führt das Programm aus und gibt die Ausgabe zurück
  • status - führt das Programm aus und gibt den Exit-Code zurück

Ein einfaches Beispiel aus den Dokumenten:

use std::process::Command;

Command::new("ls")
        .arg("-l")
        .arg("-a")
        .spawn()
        .expect("ls command failed to start");

2
Was ist, wenn ich Echtzeitausgabe erhalten muss? Ich denke, die outputFunktion gibt Vec nach Abschluss des Prozesses zurück. Also, falls wir so etwas laufen lassen Command("ping google.com"). Ist dies möglich, um diese Befehle auszugeben, da sie nicht beendet werden, aber ich möchte ihre Protokolle drucken. Bitte vorschlagen.
GrvTyagi

3
@GrvTyagi: Gibt spawnin dieser Antwort ein ChildErgebnis mit Standard-E / A-Streams zurück.
Ry-

Aufbauend auf dieser hervorragenden Antwort fand ich diese Antwort auch hilfreich, um zu verstehen, wie man mit stdin / stdout interagiert.
Michael Noguera

33

Ein sehr klares Beispiel aus den Dokumenten :

use std::process::Command;
let output = Command::new("/bin/cat")
                     .arg("file.txt")
                     .output()
                     .expect("failed to execute process");

println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

assert!(output.status.success());

8

Es ist tatsächlich möglich! Das entsprechende Modul ist std::run.

let mut options = std::run::ProcessOptions::new();
let process = std::run::Process::new("ls", &[your, arguments], options);

ProcessOptions'Standard-Dateideskriptoren sind standardmäßigNone (Erstellen einer neuen Pipe), sodass Sie process.output()(zum Beispiel) nur zum Lesen aus der Ausgabe verwenden können.

Wenn Sie den Befehl ausführen und alle seine Ausgaben erhalten möchten, nachdem er ausgeführt wurde, gibt es wait_with_outputdafür .

Process::new, seit gestern, gibt übrigens ein Option<Process>statt ein zurück Process.


31
Für alle Suchenden: std :: run wurde entfernt, siehe std::io::processstattdessen (Antwort unten).
jgillich

2
Es ist std::processjetzt ab rustc 1.19.0.
WiSaGaN
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.