如何在Go语言中使用命名管道处理进程输出

huangapple go评论93阅读模式
英文:

how to handle process output in go using named pipe

问题

我正在尝试从tmux中的一个正在运行的进程建立一个管道,以便逐行处理其输出。

我已经查看了将tmux会话的输出导向stdout的指南关于(命名)管道在Go中的文章

我已经尝试了一段时间,但仍然没有得到任何值得注意的结果。

我非常感谢任何关于如何设置该管道的想法,最好是可以逐行遍历它。

非常感谢。

英文:

I am trying to set up a pipe from a running process in tmux,
in order to handle its output line by line.

I have had a look at this guide to pipe the output of a tmux session to stdout
and this article about (named) pipes in go.

I have been trying around with that for quite a while now,
but still didn't get any noteworthy results.

I would really appreciate any thoughts on how to set that pipe up,
Ideally in a way so I can range over it linewise.

Thanks a lot

答案1

得分: 1

这是我在这里找到的解决方案(感谢Malcolm):

func Readln(r *bufio.Reader) (string, error) {
    var (
        isPrefix = true
        err      error
        line, ln []byte
    )
    for isPrefix && err == nil {
        line, isPrefix, err = r.ReadLine()
        ln = append(ln, line...)
    }
    return string(ln), err
}

func handle(s string) {
    // 对字符串进行处理
}

func main() {
    c := exec.Command("sh", "./tmuxpipe.sh")
    err := c.Run()
    if err != nil {
        log.Fatal(err)
    }

    f, err := os.Open("/tmp/tmuxpipe")
    if err != nil {
        fmt.Printf("打开文件时出错:%v\n", err)
        os.Exit(1)
    }
    r := bufio.NewReader(f)
    s, e := Readln(r)
    for e == nil {
        handle(s)
        log.Println(s)
        s, e = Readln(r)
    }
}

这是 tmuxpipe.sh 的内容:

mkfifo /tmp/tmuxpipe
tmux pipe-pane -o -t tmuxSession 'cat >> /tmp/tmuxpipe'

我之所以没有直接使用 exec.Command(),是因为出于我无法理解的原因,下面的代码在我的情况下无法正常工作:

c := exec.Command("tmux", "pipe-pane", "-o", "-t", "tmuxSession", 'cat >> /tmp/tmuxpipe') 
err := c.Run()
handleError(err)

没有发生错误,但是 tmux 会话的输出也没有显示出来。

希望这对任何人有所帮助。

英文:

Here is the solution which I found here (thank you Malcolm)

func Readln(r *bufio.Reader) (string, error) {
	var (
		isPrefix = true
		err      error
		line, ln []byte
	)
	for isPrefix && err == nil {
		line, isPrefix, err = r.ReadLine()
		ln = append(ln, line...)
	}
	return string(ln), err
}

func handle(s string) {
    //Do something with your string
}

func main() {
	c := exec.Command("sh", "./tmuxpipe.sh")
	err := c.Run()
	if err != nil {
		log.Fatal(err)
	}

	f, err := os.Open("/tmp/tmuxpipe")
	if err != nil {
		fmt.Printf("error opening file: %v\n", err)
		os.Exit(1)
	}
	r := bufio.NewReader(f)
	s, e := Readln(r)
	for e == nil {
		handle(s)
		log.Println(s)
		s, e = Readln(r)
	}
}

here is the tmuxpipe.sh:

mkfifo /tmp/tmuxpipe
tmux pipe-pane -o -t tmuxSession 'cat >> /tmp/tmuxpipe'

The reason I did not just use exec.Command() there, is because for some reason beyond my comprehension this:

c := exec.Command("tmux", "pipe-pane", "-o", "-t", "tmuxSession", 'cat >> /tmp/tmuxpipe'") 
err := c.Run()
handleError(err)

did not work (for me).
There was no error occuring, but the output of the tmux session wasn't displayd either.

I hope this helps anybody

huangapple
  • 本文由 发表于 2017年8月20日 19:28:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/45781644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定