2016-05-22 8 views
0

In meinem Go-Programm muss ich top ausführen, um einen bestimmten Prozess kontinuierlich zu überwachen. Aber top gibt mir nicht den Zeitstempel, wenn jede Zeile aufgezeichnet wird. Ich denke an das Voranstellen es an die Ausgänge mein Selbst:Go: Inhalt den Ausgaben von oben voranstellen

top := exec.Command("top", "-p", pid) 
r, w := os.Pipe() 
top.Stdout = w 
top.Start() 

So kann ich die Ausgänge von r an einem Ende des Rohres lesen kann. Ich frage mich, wie kann ich eine Aktion auslösen, um den aktuellen Zeitstempel zu bekommen und es der Ausgabe voranzustellen, wenn es eine neue Zeile von top.Stdout gibt? Ich denke, es sollte wie ein Callback oder Pythons Generator sein, aber ich bin mir nicht sicher, wie ich es in Go machen soll.

Antwort

1

Etwas entlang der Linien von:

func main() { 
    for ln := range topMon(2543) { 
     fmt.Println(time.Now().UTC().Format(time.RFC3339), ln) 
    } 
} 

func topMon(pids ...int) <-chan string { 
    ch := make(chan string, 1) 
    top := exec.Command("top", "-b") 
    for _, pid := range pids { 
     top.Args = append(top.Args, "-p", strconv.Itoa(pid)) 
    } 
    r, w, _ := os.Pipe() 
    go func() { 
     sc := bufio.NewScanner(r) 
     for sc.Scan() { 
      ch <- sc.Text() 
     } 
     close(ch) 
    }() 
    top.Stdout = w 
    top.Stderr = os.Stderr 
    if err := top.Start(); err != nil { 
     panic(err) 
    } 
    return ch 
} 

Die Kanalnutzung nur ein Beispiel ist, können Sie einfach die rwader aus dem Rohr direkt zurück.

+0

Es scheint, dass 'for' Schleife innerhalb der Goroutine für immer läuft? Wenn ich 'top.Process.Signal (os.Kill)' habe, wie kann ich dann diese goroutine stoppen? Vielen Dank. –

+0

@JFreebird 'sc.Scan()' gibt false zurück, da der Leser 'io.EOF' zurückgibt und es beendet wird. – OneOfOne