Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何调用外部程序并处理其输出?_Go - Fatal编程技术网

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

Go 如何调用外部程序并处理其输出?,go,Go,我试图调用一个外部命令,例如seq 10并获取其输出,处理输出,然后打印出处理结果。但是下面的代码不起作用。你能告诉我怎么做吗 // vim: set noexpandtab tabstop=2: package main import ( "bufio" "io" "os" "log" "os/exec" ) func main() { cm

我试图调用一个外部命令,例如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'})
    }
}
编辑:我也试过这个。但它也有错误。谁能给我举一个有效的例子吗

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

您需要使用.StdoutPipe将标准输出到读卡器,还需要使用exec.Command…Start以增量方式读取。Run将等待进程退出。 以下是工作代码:

// vim: set noexpandtab tabstop=2:

package main

import (
    "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())
}

您需要使用.StdoutPipe将标准输出到读卡器,还需要使用exec.Command…Start以增量方式读取。Run将等待进程退出。 以下是工作代码:

// vim: set noexpandtab tabstop=2:

package main

import (
    "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())
}

另一种方法和更干净的方法是使用自动处理\n或任何其他分隔符的bufio.Scanner。另一个优点是,这种方法没有种族问题,可以这样做:

包干管 进口 布菲奥 fmt 日志 操作系统/执行器 func main{ cmd:=exec.Commandseq,10 标准输出,错误:=cmd.StdoutPipe 如果错误!=零{ log.Fatalerr } err=cmd.Start 如果错误!=零{ log.Fatalfcmd.Start失败,出现%s\n错误 } stdin:=bufio.newscannerstout 标准扫描{ fmt.Printlnstdin.Text } 等等 }
扫描在EOF上返回false,该值在进程退出时给出。cmd.Wait将关闭StdoutPipe,如果退出非零,您可以读取err.exec.exitror.ExitCode以获取退出代码。

另一种方法和更干净的方法是使用自动处理\n或任何其他分隔符的bufio.Scanner。另一个优点是,这种方法没有种族问题,可以这样做:

包干管 进口 布菲奥 fmt 日志 操作系统/执行器 func main{ cmd:=exec.Commandseq,10 标准输出,错误:=cmd.StdoutPipe 如果错误!=零{ log.Fatalerr } err=cmd.Start 如果错误!=零{ log.Fatalfcmd.Start失败,出现%s\n错误 } stdin:=bufio.newscannerstout 标准扫描{ fmt.Printlnstdin.Text } 等等 }
扫描在EOF上返回false,该值在进程退出时给出。cmd.Wait将关闭StdoutPipe,如果退出非零,您可以读取err.exec.exitorror.ExitCode以获取退出代码。

中的示例应该很有用。试着先看看那里。@PaSTE示例那里不清楚。您能展示如何使用ReadBytes处理外部命令输出的完整代码吗?@user1424739:如果您想使用bufio.Reader,请使用第一条注释中的StdoutPipe,它也有一个完整的示例。@JimB我无法使它工作。你能给我看一个使用ReadBytes的工作示例吗?中的示例应该很有用。试着先看看那里。@PaSTE示例那里不清楚。您能展示如何使用ReadBytes处理外部命令输出的完整代码吗?@user1424739:如果您想使用bufio.Reader,请使用第一条注释中的StdoutPipe,它也有一个完整的示例。@JimB我无法使它工作。你能给我看一个使用ReadBytes的工作示例吗?。似乎扫描无法处理任意长的行,并且它不会返回除味器,当我需要读取最后一行时,我需要区分它。我理解正确吗?如果两种情况都是这样,那么它就不适合我的应用程序。根据那篇文章,扫描仪默认可以扫描多达64k行。此外,您可以随时追加换行字节,因此这不是什么大问题。。似乎扫描无法处理任意长的行,并且它不会返回除味器,当我需要读取最后一行时,我需要区分它。我理解正确吗?如果两种情况都是这样,那么它就不适合我的应用程序。根据那篇文章,扫描仪默认可以扫描多达64k行。另外,您也可以添加换行符字节,所以这不是什么大问题。谢谢。如何捕获外部程序的退出状态?您可以等待并读取ProcessState。我更新了示例。如何将外部程序的stderr打印到go程序的stderr?方法相同,但使用StderrPipe。谢谢。如何捕获外部程序的退出状态?您可以等待并读取ProcessState。我更新了示例。如何将外部程序的stderr打印到go程序的stderr?方法相同,但改用StderrPipe。