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)
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥200 如何使用postGis实现最短领规划?
  • ¥15 pyinstaller打包错误
  • ¥20 cesm的气溶胶排放文件
  • ¥15 逐月累计,月份不连续,补齐月份
  • ¥15 应用简单的Python代码完成一个学生成绩管理系统
  • ¥15 用matlab求微分方程初值问题
  • ¥15 vscode下编写第三方库opencv与pcl代码时没有代码提示
  • ¥15 能够跑通不报错,如何解决?(标签-matlab)
  • ¥15 MOS在RDS较大,频率高时开关波形异常
  • ¥15 SCENIC分析报错求解答