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

标签 go

我正在尝试调用一个外部命令(例如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'})
    }
}

最佳答案

另一种方法(也是一种更清洁的方法)是使用bufio.Scanner,它可以自动处理\n(或任何其他定界符)。另一个优点是,此方法没有种族问题(在那里完成了):

package main

import (
    "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()EOF上返回false,一旦进程退出就给出。 cmd.Wait()将关闭StdoutPipe,您可以阅读err.(exec.ExitError).ExitCode()以获得退出代码(如果退出为非零)。

关于go - 如何调用外部程序并处理其输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62586549/

相关文章:

arrays - 如何在结构中附加 slice

go - 用 Go 判断 Stdin 是否有数据

go - 目前仅支持 JMSCorrelationID 上的选择器

go - 字节数组转换为字符串

go - 在go中声明空类型

go - 如何定义一个空变量来存储 File 结构的值?

encryption - 从 PHP 到 Go 的 Mcrypt

go - 使用go.mod在目录中将软件包安装到GOPATH

html - go/golang 服务器中的静态 css 文件

go - 导入语句的使用