Comment appeler une commande système dans Rust et capturer sa sortie?

87

Existe-t-il un moyen d'appeler une commande système, comme lsou fuserdans Rust? Que diriez-vous de capturer sa sortie?

quux00
la source

Réponses:

115

std::process::Command permet cela.

Il existe plusieurs façons de générer un processus enfant et d'exécuter une commande arbitraire sur la machine:

  • spawn - exécute le programme et renvoie une valeur avec des détails
  • output - exécute le programme et renvoie la sortie
  • status - exécute le programme et renvoie le code de sortie

Un exemple simple tiré de la documentation:

use std::process::Command;

Command::new("ls")
        .arg("-l")
        .arg("-a")
        .spawn()
        .expect("ls command failed to start");
talles
la source
2
Et si j'ai besoin d'obtenir une sortie en temps réel. Je pense que la outputfonction renvoie Vec après la fin du processus. Donc, au cas où nous exécutions quelque chose comme Command("ping google.com"). Est-ce possible d'obtenir cette sortie de commandes car elle ne se terminera pas, mais je veux imprimer ses journaux. Veuillez suggérer.
GrvTyagi
3
@GrvTyagi:, spawnmentionné dans cette réponse, renvoie un Childrésultat avec des flux d'E / S standard.
Ry-
Sur la base de cette excellente réponse, j'ai également trouvé cette réponse utile pour comprendre comment interagir avec stdin / stdout.
Michael Noguera
33

un exemple très clair de la documentation :

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());
Karan Ahuja
la source
8

C'est en effet possible! Le module pertinent est std::run.

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

ProcessOptionsLes descripteurs de fichier standard sont par défautNone (créer un nouveau tube), vous pouvez donc simplement utiliser process.output()(par exemple) pour lire à partir de sa sortie.

Si vous voulez exécuter la commande et obtenir toute sa sortie une fois que c'est fait, il y a wait_with_outputpour cela .

Process::new, à partir d'hier, renvoie un Option<Process>au lieu de a Process, d'ailleurs.

Ry-
la source
31
Pour tous les chercheurs: std :: run a été supprimé, voir à la std::io::processplace (réponse ci-dessous).
jgillich
2
C'est std::processmaintenant à partir de rustc 1.19.0.
WiSaGaN