如何调用外部程序并处理其输出?

我正在尝试调用外部命令(例如,seq 10)并获取其输出,处理输出然后打印出处理后的结果。但是下面的代码不起作用。你能告诉我如何让它工作吗?


// vim: set noexpandtab tabstop=2:


package main


import (

    "bufio"

    "io"

    "os"

    "log"

    "os/exec"

)


func main() {

    cmd := exec.Command("seq", "10")

    stdin := bufio.NewReader(cmd.Stdout)

    err := cmd.Run()

    if err != nil {

        log.Fatalf("cmd.Run() failed with %s\n", err)

    }


    for {

        line, err := stdin.ReadBytes('\n')

        if err == io.EOF {

            if len(line) == 0 { break }

        } else {

            if err != nil { log.Fatal(err) }

            line = line[:(len(line)-1)]

        }

        os.Stdout.Write(line)

        os.Stdout.Write([]byte{'\n'})

    }

}

$ $ go run main.go 

# command-line-arguments

./main.go:15:30: cannot use cmd.Stdout (type io.Writer) as type io.Reader in argument to bufio.NewReader:

    io.Writer does not implement io.Reader (missing Read method)

编辑:我也试过这个。但它也有错误。谁能给我看一个可行的例子。


// vim: set noexpandtab tabstop=2:


package main


import (

    "bufio"

    "io"

    "os"

    "log"

    "os/exec"

)


func main() {

    cmd := exec.Command("seq", "10")

    stdout, err := cmd.StdoutPipe()

    if err != nil { log.Fatal(err) }


    stdin := bufio.NewReader(stdout)

    err = cmd.Run()

    if err != nil {

        log.Fatalf("cmd.Run() failed with %s\n", err)

    }


    for {

        line, err := stdin.ReadBytes('\n')

        if err == io.EOF {

            if len(line) == 0 { break }

        } else {

            if err != nil { log.Fatal(err) }

            line = line[:(len(line)-1)]

        }

        os.Stdout.Write(line)

        os.Stdout.Write([]byte{'\n'})

    }

}


千万里不及你
浏览 178回答 2
2回答

万千封印

另一种方法(也是一种更简洁的方法)是自动使用bufio.Scanner哪个句柄\n(或任何其他分隔符)。另一个优点是这种方法没有种族问题(去过那里,做过):package mainimport (    "bufio"    "fmt"    "log"    "os/exec")func main() {    cmd := exec.Command("seq", "10")    stdout, err := cmd.StdoutPipe()    if err != nil {        log.Fatal(err)    }    err = cmd.Start()    if err != nil {        log.Fatalf("cmd.Start() failed with %s\n", err)    }    stdin := bufio.NewScanner(stdout)    for stdin.Scan() {        fmt.Println(stdin.Text())    }    cmd.Wait()}stdin.Scan()返回 false on EOF,一旦进程退出就会给出。cmd.Wait()将关闭StdoutPipe,您可以阅读err.(exec.ExitError).ExitCode()以获取退出代码(如果退出非零)。

jeck猫

您需要使用管道将标准输出到阅读器.StdoutPipe(),还需要使用exec.Command(..).Start()增量读取(.Run()等待进程退出)。这是工作代码:// vim: set noexpandtab tabstop=2:package mainimport (    "bufio"    "fmt"    "io"    "log"    "os"    "os/exec")func main() {    cmd := exec.Command("seq", "10")    cmdStdOut, err := cmd.StdoutPipe()    cmdStdErr, err := cmd.StderrPipe()    defer cmdStdOut.Close()    if err != nil {        log.Fatalf("command failed with %s\n", err)    }    stdoutReader := bufio.NewReader(cmdStdOut)    stderrReader := bufio.NewReader(cmdStdErr)    err = cmd.Start()    if err != nil {        log.Fatalf("cmd.Run() failed with %s\n", err)    }    // Read stdout    for {        line, err := stdoutReader.ReadBytes('\n')        if err == io.EOF {            if len(line) == 0 {                break            }        } else {            if err != nil {                log.Fatal(err)            }            line = line[:(len(line) - 1)]        }        os.Stdout.Write(line)        os.Stdout.Write([]byte{'\n'})    }    // Read stderr    for {        line, err := stderrReader.ReadBytes('\n')        if err == io.EOF {            if len(line) == 0 {                break            }        } else {            if err != nil {                log.Fatal(err)            }            line = line[:(len(line) - 1)]        }        os.Stderr.Write(line)        os.Stderr.Write([]byte{'\n'})    }    cmd.Wait()    fmt.Println(cmd.ProcessState.ExitCode())}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go