In Szenarien, in denen ein lang andauernder Befehl ausgeführt wird und seine Ausgabe kontinuierlich sowohl an den übergeordneten Prozess als auch an eine Protokolldatei gestreamt werden muss , kann die cmd.StdoutPipe()-Methode verwendet werden, um die Ausgabe zu erfassen.
cmd := exec.Command("sh", "-c", "some long runnig task") stdout, _ := cmd.StdoutPipe() cmd.Start() scanner := bufio.NewScanner(stdout) for scanner.Scan() { m := scanner.Text() fmt.Println(m) log.Printf(m) } cmd.Wait()
Dieser Ansatz liefert jedoch nur die endgültige Ausgabe als einzelne Ausgabe Zeichenfolge, kein Streaming von Teilergebnissen.
Die Funktion bufio.NewScanner() arbeitet mit Zeilen und gibt eine vollständige Zeile zurück, wenn ein Zeilenumbruchzeichen angetroffen wird. Wenn der ausgeführte Befehl keine Zeilenumbrüche erzeugt, wird die Ausgabe nicht sofort gestreamt.
Um diese Einschränkung zu beheben, sind mehrere Ansätze zu berücksichtigen:
Lesen nach Wörtern oder Zeichen:
Durch Festlegen einer Teilungsfunktion mit Mit Scanner.Split() können Sie die Eingabe nach Wörtern oder Zeichen scannen und die Ausgabe erfassen, während sie erzeugt wird.
scanner := bufio.NewScanner(stdout) scanner.Split(bufio.ScanRunes)
Manuelles Lesen:
Durch das Byte-für-Byte- oder Rune-für-Rune-Lesen können Sie die Ausgabe erfassen, während sie generiert wird, ohne auf Zeilenumbrüche angewiesen zu sein Zeichen.
oneByte := make([]byte, 1) for { _, err := stdout.Read(oneByte) if err != nil { break } fmt.Printf("%c", oneByte[0]) } oneRune := make([]byte, utf8.UTFMax) for { count, err := stdout.Read(oneRune) if err != nil { break } fmt.Printf("%s", oneRune[:count]) }
Es ist wichtig, Puffergrößen für Standardausgaben und Fehlerströme in untergeordneten Prozessen zu verwalten. Wenn diese Puffer nicht gelesen werden, kann dies standardmäßig dazu führen, dass der untergeordnete Prozess hängen bleibt. Daher wird empfohlen, immer sowohl den stdout- als auch den stderr-Stream zu lesen.
Das obige ist der detaillierte Inhalt vonWie streame ich die Teilausgabe eines Befehls mit langer Laufzeit in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!