douxuanyi2813 2016-05-19 17:28
浏览 34
已采纳

GO:使用管道执行命令[重复]

This question already has an answer here:

I wonder whether there's a way to run top -b | grep --line-buffered [some_pid] >> out.log in Go for a certain amount of time and then kill it after receiving a value from the channel. The os.exec doesn't seem to support piping in command. Thanks.

</div>
  • 写回答

1条回答 默认 最新

  • doukuang1950 2016-05-19 22:20
    关注

    this is my piping sample, file a calls file b via OS Std Pipe, you can edit this and add timer to do what you need.

    // a
    package main
    
    import (
        "fmt"
        "log"
        "os/exec"
        "runtime"
        "time"
    )
    
    var cout chan []byte = make(chan []byte)
    var cin chan []byte = make(chan []byte)
    var exit chan bool = make(chan bool)
    
    func Foo(x byte) byte { return call_port([]byte{1, x}) }
    func Bar(y byte) byte { return call_port([]byte{2, y}) }
    func Exit() byte      { return call_port([]byte{0, 0}) }
    func call_port(s []byte) byte {
        cout <- s
        s = <-cin
        return s[1]
    }
    
    func start() {
        fmt.Println("start")
        cmd := exec.Command("../b/b")
        stdin, err := cmd.StdinPipe()
        if err != nil {
            log.Fatal(err)
        }
        stdout, err2 := cmd.StdoutPipe()
        if err2 != nil {
            log.Fatal(err2)
        }
        if err := cmd.Start(); err != nil {
            log.Fatal(err)
        }
        defer stdin.Close()
        defer stdout.Close()
        for {
            select {
            case s := <-cout:
                stdin.Write(s)
                buf := make([]byte, 2)
                runtime.Gosched()
                time.Sleep(100 * time.Millisecond)
                stdout.Read(buf)
                cin <- buf
            case b := <-exit:
                if b {
                    fmt.Printf("Exit")
                    return //os.Exit(0)
                }
            }
        }
    }
    func main() {
        go start()
        runtime.Gosched()
        fmt.Println("30+1=", Foo(30)) //30+1= 31
        fmt.Println("2*40=", Bar(40)) //2*40= 80
        Exit()
        exit <- true
    }
    

    file b:

    // b
    package main
    
    import (
        "log"
        "os"
    )
    
    func foo(x byte) byte { return x + 1 }
    func bar(y byte) byte { return y * 2 }
    
    func ReadByte() byte {
        b1 := make([]byte, 1)
        for {
            n, _ := os.Stdin.Read(b1)
            if n == 1 {
                return b1[0]
            }
        }
    }
    func WriteByte(b byte) {
        b1 := []byte{b}
        for {
            n, _ := os.Stdout.Write(b1)
            if n == 1 {
                return
            }
        }
    }
    func main() {
        var res byte
        for {
            fn := ReadByte()
            log.Println("fn=", fn)
            arg := ReadByte()
            log.Println("arg=", arg)
            if fn == 1 {
                res = foo(arg)
            } else if fn == 2 {
                res = bar(arg)
            } else if fn == 0 {
                return //exit
            } else {
                res = fn //echo
            }
            WriteByte(1)
            WriteByte(res)
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 'Content-Type': 'application/x-www-form-urlencoded' 请教 这种post请求参数,该如何填写??
  • ¥15 找代写python里的jango设计在线书店
  • ¥15 请教如何关于Msg文件解析
  • ¥200 sqlite3数据库设置用户名和密码
  • ¥15 AutoDL无法使用docker install吗?
  • ¥15 cups交叉编译后移植到tina sdk的t113,只需要实现usb驱动打印机,打印pdf文件
  • ¥30 关于#wireshark#的问题:需要网络应用流量数据集需要做长度序列的实验,需要与应用产生的会话的数据包的长度,如视频类或者聊天类软件
  • ¥15 根据上述描述表示泥浆密度沿着管路的长度方向在不断变化,如何来表示泥浆密度随管路的变化(标签-matlab|关键词-流计算)
  • ¥21 matlab可以把图像数据转换为小波分析吗
  • ¥60 基于香农编码的图像压缩算法实现