Ich möchte in der Lage sein, Rust zu verwenden, um eine Child-Shell zu erzeugen, dann wiederhole ich sie willkürlich und verarbeite ihre Ausgaben. Ich habe viele Beispiele online gefunden, die mir zeigen, wie man einen einzelnen Befehl übergibt und seine einzige Ausgabe erhält, aber ich kann es nicht immer wieder tun.Konnte nicht mehr als einmal in den oder aus dem erzeugten Child-Prozess pipen
Zum Beispiel hängt der folgende Code in der Zeile nach dem Kommentar. (Ich stelle mir vielleicht read_to_string()
blockiert wird, bis er von dem Kind Prozess stdout erhält, aber wenn so verstehe ich nicht, warum das Ausgangs ausbleibt ..)
let mut child_shell = match Command::new("/bin/bash")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
{
Err(why) => panic!("couldn't spawn child_shell: {}", Error::description(&why)),
Ok(process) => process,
};
loop {
{
match child_shell.stdin.as_mut().unwrap().write("ls".as_bytes()) {
Err(why) => panic!(
"couldn't send command to child shell: {}",
Error::description(&why)
),
Ok(_) => println!("sent command to child shell"),
}
}
{
let mut s = String::new();
// ↓ hangs on this line ↓
match child_shell.stdout.as_mut().unwrap().read_to_string(&mut s) {
Err(why) => panic!("couldn't read bash stdout: {}", Error::description(&why)),
Ok(_) => print!("bash responded with:\n{}", s),
}
}
}
ich ein Anfänger in Rust bin und ich Ich denke, das Problem ist mein begrenztes Verständnis der borrow-checker/referenzierenden Regeln, da das obige gut läuft (für eine einzige Iteration), wenn ich die Schleifenanweisung aus dem Code entferne und die Referenzen auf die Innereien der std::process::Child
struct in unveränderlich ändere; zum Beispiel aus dieser:
child_shell.stdin.as_mut().unwrap().write("ls".as_bytes())
dazu:
child_shell.stdin.unwrap().write("ls".as_bytes())
Offensichtlich wiederholt ausgeführt ls
nicht mein Ziel ist es, und ich weiß, dass ich nur ein Shell-Skript schreiben könnte und dann haben Rust wiederholt mach es - aber (abgesehen von dem Ziel, nur mehr über Rust zu lernen!) muss ich zumindest prinzipiell für ein komplizierteres Projekt tun können (auf das ich mich gerne einlasse, wenn es möglich ist) sich für irgendwelche Lösungen als relevant erweisen, aber es ist wahrscheinlich, Weg, weit außerhalb des Umfangs dieser Frage!)
Schließlich, wenn es sich herausstellt, dass es nicht möglich ist, eine Kind-Shell auf diese Weise zu verwenden, würde ich dennoch gerne lernen, wie man wiederholt und kontinuierlich einen und einen anderen beliebigen Befehl ausführt, wie ich konnte keine Informationen in der Rust Dokumentation, Tutorials oder auf Stack Overflow finden.
Vielen Dank! Alle wirklich nützlichen Ratschläge und Beobachtungen. Im Hinblick darauf, herauszufinden, wann das Lesen aus dem 'BufReader' gestoppt werden sollte, warum versucht man einfach, child_out.lines(). Count() 'oder' for l in child_out.lines() 'innerhalb der Schleife aufzurufen gibt mir eine 'Verwendung von verschobenem Wert: child_out' Fehler? Warum kann ich den "BufReader" für eine Zeile fragen, aber nicht für alle? Mißverstehe ich, wie Iteratoren hier arbeiten? – John
@John nicht wie Iteratoren arbeiten, aber wie der 'self' Parameter bei diesen Methoden funktioniert. Check out ['count'] (http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.count) um zu sehen, dass es" self "nach Wert nimmt, was den zugrundeliegenden Iterator verbraucht , wie [Zeilen] (http://doc.rust-lang.org/std/io/trait.BufRead.html#method.lines). Der Aufruf von 'count' würde sowieso keinen Sinn ergeben, da man * all * der Prozessausgabe lesen müsste, um die Zählung zu erhalten, in der alle Daten weggeworfen würden. – Shepmaster