一尘不染

GO:使用管道执行命令

go

我想知道是否有一种方法可以top -b | grep --line-buffered [some_pid] >> out.log在Go中运行一定的时间,然后在从通道接收到值后将其杀死。在os.exec似乎不支持命令管道。谢谢。


阅读 242

收藏
2020-07-02

共1个答案

一尘不染

这是我的管道示例,通过OS Std Pipe归档一个调用文件b,您可以对其进行编辑并添加计时器以执行所需的操作。

// 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
}

文件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)
    }
}
2020-07-02