0

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 以外のソリューションである可能性があります)。

4

1 に答える 1

3

このような問題は通常、stdin / stdout / stderr が正確に何であるかに応じてデフォルトのバッファリング モードを変更する C ライブラリに関係しています。

stdout が端末の場合、バッファリングは自動的にライン バッファリングに設定されます。それ以外の場合は、バッファリングに設定されます。

パイプを介してプログラムを実行すると、プログラムは端末に接続されないため、この種の使用を台無しにするバッファリングが発生するため、これはあなたに関係があります。

修正するには、端末のふりをしてパイプのように振る舞う疑似 tty を使用する必要があります。これは、私が実際に試したことのないpty インターフェイスを実装したライブラリですが、正しいことをしているようです!

于 2013-02-09T15:13:40.370 に答える