duanlv5084 2016-05-22 21:41
浏览 7
已采纳

转至:从顶部将内容添加到输出

In my go program, I need to run top to continuously monitoring a specific process. But top does not give me the timestamp when each line is recorded. I'm thinking about prepending it to the outputs my self:

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

This way I can read the outputs from r at one end of the pipe. I wonder how can I fire an action to get the current timestamp and prepend it to the output whenever there's a new line from top.Stdout? I think it should be like a callback or Python's generator, but I'm not sure how to do it in Go.

  • 写回答

1条回答 默认 最新

  • douxunnian0423 2016-05-22 22:13
    关注

    Something along the lines of:

    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
    }
    

    The channel usage is just an example, you can just return the rwader from the pipe directly.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?