Goland阅读班轮每行输出一个命令

时间:2016-02-05 10:16:58

标签: go

我想读取每行的输出命令行。为此,我使用StdoutPipe方法和bufio库:

package main

import (
        "encoding/json"
        "fmt"
        "log"
        "os/exec"
        "bufio"
)


func main() {
        cmd := exec.Command("printf", "{\"Name\": \"Bob\", \"Age\": 1}\n%.0s", "{1..5}")
        stdout, err := cmd.StdoutPipe()
        if err != nil {
                log.Fatal(err)
        }
        scanner := bufio.NewScanner(stdout)
        if err := cmd.Start(); err != nil {
                log.Fatal(err)
        }
        var person struct {
                Name string
                Age  int
        }
        for scanner.Scan() {
                if err := json.Unmarshal([]byte(scanner.Text()), &person); err != nil {
                        log.Fatal(err)
                } else {
                        fmt.Printf("%s is %d years old\n", person.Name, person.Age)
                }
        }
        if err := cmd.Wait(); err != nil {
                log.Fatal(err)
        }
}

我应该获得5行:

$ printf "{\"Name\": \"Bob\", \"Age\": 1}\n%.0s" {1..5}
{"Name": "Bob", "Age": 1}
{"Name": "Bob", "Age": 1}
{"Name": "Bob", "Age": 1}
{"Name": "Bob", "Age": 1}
{"Name": "Bob", "Age": 1}

关键是我只得到了第一行。我在Go上很新,我猜StdoutPipe的用法不正确。

1 个答案:

答案 0 :(得分:1)

shell将

{1..5}扩展为1 2 3 4 5,因此您必须自己执行此操作:

cmd := exec.Command("printf", `{"Name": "Bob", "Age": %s}\n`, `1`, `2`) // etc.

还要注意使用原始字符串,它比不断逃避一切更方便。在相关的说明中,您应该使用[]byte(scanner.Text())而不是scanner.Bytes()