Ich versuche, einen Shell-Prozess in Go zu starten. Dies ist mein Code:Shell/Bash in Go ausführen
func StartShell() (*Shell, error) {
cmd := exec.Command("sh")
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, err
}
stdin, err := cmd.StdinPipe()
if err != nil {
return nil, err
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
if err := cmd.Start(); err != nil {
return nil, err
}
sh := &Shell{
cmd: cmd,
stderr: stderr,
stdin: stdin,
stdout: stdout,
}
// this will read forever, but it is only for ilustrative purposes
for {
b := make([]byte, 2048)
fmt.Println(stdout.Read(b))
}
return sh, nil
}
Wenn ich oben Funktion ausführen, wie es ist, ich werde keine Ausgabe erhalten, aber wenn ich sh
-cmd
und führen Sie es unter Windows zu ändern, druckt er einige Daten am Anfang und wartet für immer (das ist OK). Beispiel Ausgabe:
36 <nil>
129 <nil>
Dies führte mich zu denken, dass es Linux Weg sein kann. Also habe ich den Befehl in ls
geändert und unter Linux ausgeführt. Kurz gesagt: Es funktioniert wie erwartet.
Als nächstes leitete ich stdout, stderr und stdin zu den Prozess ein. Ich habe gerade über cmd.Start()
folgende Snippet hinzugefügt:
// without those three below, `sh` would not print anything to stdout
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
Wenn nun ausgeführt, ich habe voll funktions sh
Prozess zu meinem Terminal umgeleitet. Es funktioniert nur, wenn alle 3 Streams umgeleitet werden.
Warum passiert das? Im Idealfall möchte ich den Shell-Prozess im Hintergrund starten und Befehle innerhalb dieser Shell ausführen, ohne sie auf das Terminal zu drucken. (Ich bin mir bewusst, dass dies keine optimale Lösung ist.)
Aber für mich wird erwartet, dass der Prozess nicht beendet wird. Ich versuche, die Bytes zu lesen, sobald sie gesendet werden. Ich habe Ihr Snippet eins zu eins implementiert und dann aus dem 'out' Puffer gelesen - immer noch nada. –