【问题标题】:GO: Execute a Command with Pipe [duplicate]GO:使用管道执行命令 [重复]
【发布时间】:2016-09-16 17:54:44
【问题描述】:

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

【问题讨论】:

  • 您可以读取标准输出并将那里的输出用作另一个命令的输入。
  • 你必须按照@evanmcdonnal 所说的去做。获取top -b 的输出并将其用作grep --line-buffered [pid] 的输入;获取它的输出并将其写入文件。
  • 使用cmd2.Stdin,_ := cmd1.StdoutPipe()链接命令,然后按顺序运行。
  • 看看this问题

标签: go


【解决方案1】:

这是我的管道示例,通过 OS Std Pipe 归档 a 调用文件 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)
    }
}

【讨论】:

    最近更新 更多