Golang - Kopie Exec-Ausgang zu Melden
Ich würde gerne die Umleitung der Ausgabe eines Prozesses zu log
in einer fristgerechten Weise. Ich kann es tun, wenn ich warten, bis der Prozess fertig zu stellen wie diese:
cmd := exec.Command("yes", "Go is awesome") //Prints "Go is awesome", forever
out, err := cmd.CombinedOutput()
log.Printf("%s", out)
Allerdings, wenn der Prozess dauert eine lange Zeit oder nicht fertig stellen, dies ist weniger nützlich. Ich weiß, ich kann nach stdout schreiben in Echtzeit wie diese:
cmd := exec.Command("yes")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
Dies nicht wirklich helfen, mir aber, denn ich Schreibe einen service, der nicht schreiben auf ein terminal. Ich bin auf der Suche nach etwas, lassen Sie mich etwas zu tun:
cmd := exec.Command("yes")
cmd.Stdout = log.Stdout
cmd.Stderr = log.Stdout
cmd.Run()
log
nicht geben direkten Zugriff auf die writer so ist dies nicht möglich. Ich bin sicherlich nicht der einzige mit diesem problem, wie wird das normalerweise gemacht?
- Dies wird verursacht durch Pufferung in dem Befehl, den Sie ausgeführt werden. Vielleicht finden Sie die Antworten auf diese Frage nützlich.
- Während das ist in der Tat eine gute Frage für die Erklärung der Pufferung, ich bin mir ziemlich sicher, dass dies nicht ein problem der Pufferung. CombinedOutput() wartet, bis das Programm zu beenden und gibt den Ausgang und den Befehl cmd ein.Stdout = os.Stdout nicht das problem aufweisen, aber schreibt zu einem unerwünschten Ausgang. Danke für den Kommentar, aber...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie eine Rohr hier zum Beispiel:
Habe ich nur behandelt
Stdout
hier, aber es ist möglich, behandelnStderr
zur gleichen Zeit, zum Beispiel mit einer goroutine.multi := io.MultiReader(stdout, stderr)
. Dann tunin := bufio.NewScanner(multi)
. Dies ermöglicht es einem einzelnen scanner und keine goroutine, die ich denke, ist ganz nett. Ich denkescanner.Err()
solltein.Err()
. Ich nahm diereturn 0, err
und schaffte es geradereturn err
. Super Antwort, danke!Beide
exec.Command
undlog.Logger
basieren auf einerio.Writer
. Sie haben keinen Zugang zu denen des zweiten, aber Sie brauchen nicht zu, weil Sie entweder nicht verändert, und du bist mitos.Stderr
oder Sie es geändert und Sie haben dieio.Writer
an-hand bei der Erstellung der logger.Also, Sie müssen nur passen Sie zweite Beispiel, indem Sie mit der rechten
io.Writer
...Bearbeiten
Nachdem einige wenn auf es, denke ich, können Sie gut zu gehen nur durch die Einbettung
log.Logger
in ein struct, dass die Umsetzung derio.Writer
Schnittstelle...Beispiel:
Und dann übergeben es an Ihre
exec.Command
Ausgabe...Können Sie es verwenden, für standard-oder Fehler-Ausgang, oder erstellen neues Objekt für jeden.
Edit2
Wie werde ich mit diesem trick, für eines meiner nächsten Projekte, habe ich Sie in einem Paket auf github. Fühlen Sie sich frei, um feedback zu geben, usw.