go - 使用管道与程序进程通信

标签 go ipc pipe

我希望在从 Golang 程序中生成某些程序后能够与它们完全通信。我已经拥有的是基于从 stdout 读取的最后一行的生成过程和管道对话:

package main

import (
    "fmt"
    "io"
    "log"
    "os/exec"
    "strings"
)

var stdinPipe io.WriteCloser
var stdoutPipe io.ReadCloser
var err error

func main() {
    cmd := &exec.Cmd{
        Path: "/Users/seba/Projects/go/src/bootstrap/in",
        Args: []string{"program"},
    }

    stdinPipe, err = cmd.StdinPipe()

    if err != nil {
        log.Fatal(err)
    }

    stdoutPipe, err = cmd.StdoutPipe()

    if err != nil {
        log.Fatal(err)
    }

    err = cmd.Start()

    if err != nil {
        log.Fatal(err)
    }

    var stdoutLines []string
    go stdoutManage(stdoutLines, stdoutController)

    cmd.Wait()
}

// TODO: imporove as in io.Copy
func stdoutManage(lines []string, manager func(string)) {
    buf := make([]byte, 32*1024)

    for {
        nr, err := stdoutPipe.Read(buf)

        if nr > 0 {
            thelines := strings.Split(string(buf), "\n")
            for _, l := range thelines {
                manager(l)
                lines = append(lines, l)
            }
        }

        buf = make([]byte, 32*1024) // clear buf

        if err != nil {
            break
        }
    }
}

但是,这种方法在程序清除终端输出和以某种方式缓冲标准输入或根本不使用标准输入的程序(不知道是否可能)方面存在问题。

所以问题是:是否有一种与程序对话的可移植方式(它可以是非 Golang 解决方案)?

最佳答案

像这样的问题通常与 C library which changes its default buffering 有关模式具体取决于 stdin/stdout/stderr 是什么。

如果 stdout 是终端,则缓冲自动设置为行缓冲,否则设置为缓冲。

这与您相关,因为当您通过管道运行程序时,它们没有连接到终端,因此会有缓冲,这会扰乱这种使用。

要解决这个问题,您需要使用伪装成终端但实际上就像管道一样工作的伪 tty。这是一个实现 the pty interface 的库我还没有真正尝试过,但看起来它做对了!

关于go - 使用管道与程序进程通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14788777/

相关文章:

c++ - 如何防止C/C++中的缓冲区溢出?

macos - 无法在本地主机上启动 Go 服务器

c++ - 在共享内存中的 boost 图中插入 boost vector

unix - 时间:2019-05-17 标签:c++pipe: does it wait on write

Bash tail 命令和多个管道

Android IPC LocalSocket 与 Binder (AIDL)

unit-testing - 如何在执行所有 go 测试文件之前从 .yaml 文件加载配置?

arrays - 从 JSON 数组列表中检索未知的键名和值

macos - 如何分发 OSX cli/server 应用程序

Java 和 C++ 共享内存