猿问

如何在 Golang 中通过 STDIN/STDOUT 同时连接多个程序读/写?

在高层次上,我想完成以下工作。每个框都是一个正在运行的程序,从 STDIN 读取并写入 STDOUT。我想编写一个 golang 程序来设置并运行它,以便所有生产/消费并行发生。我正在考虑使用 io.Pipe、channels 和 os.Exec 等。


                            +-----------+                                  

                            |  PROG-1   +-----------------------+          

                +---------> |           |                       v          

                |           +-----------+                                  

                |                                           +-------+      

    +-----------+                                           | DIFF  +----->

    | GENERATOR |                                           |       |      

    +-----------+                                           +---+---+      

                |                                               ^          

                |                                               |          

                |           +-----------+                       |          

                |           |           |                       |          

                +---------> |  PROG-2   +-----------------------+          

                            +-----------+                                  

这是一个尝试,但它似乎不能可靠地工作,而且“DIFF”部分也没有实现。


package main


import (

    "io"

    "os"

    "os/exec"

)


const UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

const LOWER = "abcdefghijklmnopqrstuvwxyz"


func runProg(r io.Reader, cmd *exec.Cmd) {

    cmd.Stdin = r

    cmd.Stdout = os.Stdout // I want this to go to a third prog call "diff".

    cmd.Run()

}



慕容3067478
浏览 307回答 1
1回答

喵喵时光机

这里有几件事。您在创建所有这些管道时增加了工作量和复杂性。此外,使用 Cmd.Start() 和 Cmd.Wait() 内置同时运行命令。package mainimport (        "fmt"        "io"        "os"        "os/exec")const UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"const LOWER = "abcdefghijklmnopqrstuvwxyz"func runProg(cmd *exec.Cmd) (w io.WriteCloser, err error) {        w, err := cmd.StdinPipe()        if err != nil {                fmt.Println(err)        }        cmd.Stdout = os.Stdout        err = cmd.Start()}func runIt(r io.Reader, prog1 *exec.Cmd, prog2 *exec.Cmd) {        w1, err := runProg(prog1)        if err != nil {                fmt.Println(err)        }        w2, err := runProg(prog2)        if err != nil {                fmt.Println(err)        }        go func() {                defer w1.Close()                defer w2.Close()                mw := io.MultiWriter(w1, w2)                io.Copy(mw, r)        }()}func main() {        generator := exec.Command("ls", "-l")        r, err := generator.StdoutPipe()        if err != nil {                fmt.Println(err)        }        prog1 := exec.Command("tr", LOWER, UPPER)        prog2 := exec.Command("tr", UPPER, LOWER)        runIt(r, prog1, prog2)        generator.Run()        err = prog1.Wait()        err1 := prog2.Wait()        if err != nil || err1 != nil {                fmt.Println(err, err1)        }}
随时随地看视频慕课网APP

相关分类

Go
我要回答