Przekierowanie rury stdout procesu potomnego w Go
Piszę program w Go, który wykonuje program podobny do serwera (również Go). Teraz chcę mieć stdout programu potomnego w moim oknie terminala, w którym uruchomiłem program rodzica. Jednym ze sposobów na to jest funkcja cmd.Output()
, ale wypisuje stdout dopiero po zakończeniu procesu. (To jest problem, ponieważ ten serwer podobny program działa przez długi czas i chcę przeczytać wyjście dziennika)
Zmienna out
jest z type io.ReadCloser
i nie wiem co z nią zrobić aby wykonaj moje zadanie i nie mogę znaleźć w sieci nic pomocnego na ten temat.
func main() {
cmd := exec.Command("/path/to/my/child/program")
out, err := cmd.StdoutPipe()
if err != nil {
fmt.Println(err)
}
err = cmd.Start()
if err != nil {
fmt.Println(err)
}
//fmt.Println(out)
cmd.Wait()
}
Wyjaśnienie kodu: odkomentuj funkcję Println
Aby uzyskać kod do kompilacji, wiem, że Println(out io.ReadCloser)
nie jest funkcją znaczącą.
(generuje wyjście &{3 |0 <nil> 0}
) te dwie linie są po prostu wymagane, aby uzyskać kod do kompilacji.
3 answers
Teraz chcę mieć stdout programu potomnego w moim terminalu okno, w którym uruchomiłem program rodzica.
Nie trzeba zadzierać z rurami lub goroutines, ten jest łatwy.
func main() {
// Replace `ls` (and its arguments) with something more interesting
cmd := exec.Command("ls", "-l")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 23:06:24
Uważam, że jeśli zaimportujesz io
i os
i zastąpisz to:
//fmt.Println(out)
Z tym:
go io.Copy(os.Stdout, out)
(patrz dokumentacja dla io.Copy
i dla os.Stdout
), zrobi to, co chcesz. (Zastrzeżenie: nie testowane.)
Przy okazji, prawdopodobnie będziesz chciał również przechwycić standard-error, używając tego samego podejścia, co dla standard-output, ale z cmd.StderrPipe
i os.Stderr
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-16 02:22:19
Dla tych, którzy nie potrzebują tego w pętli, ale chcieliby, aby wyjście polecenia odbijało się echem w terminalu bez blokowania innych instrukcji cmd.Wait()
:
package main
import (
"fmt"
"io"
"log"
"os"
"os/exec"
)
func checkError(err error) {
if err != nil {
log.Fatalf("Error: %s", err)
}
}
func main() {
// Replace `ls` (and its arguments) with something more interesting
cmd := exec.Command("ls", "-l")
// Create stdout, stderr streams of type io.Reader
stdout, err := cmd.StdoutPipe()
checkError(err)
stderr, err := cmd.StderrPipe()
checkError(err)
// Start command
err = cmd.Start()
checkError(err)
// Don't let main() exit before our command has finished running
defer cmd.Wait() // Doesn't block
// Non-blockingly echo command output to terminal
go io.Copy(os.Stdout, stdout)
go io.Copy(os.Stderr, stderr)
// I love Go's trivial concurrency :-D
fmt.Printf("Do other stuff here! No need to wait.\n\n")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-03 11:50:04