Goland逐行读取命令的输出结果

huangapple go评论98阅读模式
英文:

Goland reading liner per line output of a command

问题

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

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "os/exec"
  7. "bufio"
  8. )
  9. func main() {
  10. cmd := exec.Command("printf", "{\"Name\": \"Bob\", \"Age\": 1}\n%.0s", "{1..5}")
  11. stdout, err := cmd.StdoutPipe()
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. scanner := bufio.NewScanner(stdout)
  16. if err := cmd.Start(); err != nil {
  17. log.Fatal(err)
  18. }
  19. var person struct {
  20. Name string
  21. Age int
  22. }
  23. for scanner.Scan() {
  24. if err := json.Unmarshal([]byte(scanner.Text()), &person); err != nil {
  25. log.Fatal(err)
  26. } else {
  27. fmt.Printf("%s is %d years old\n", person.Name, person.Age)
  28. }
  29. }
  30. if err := cmd.Wait(); err != nil {
  31. log.Fatal(err)
  32. }
  33. }

我应该得到5行输出:

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

问题在于我只得到了第一行。我对Go不太熟悉,我猜测StdoutPipe的使用方法不正确。

英文:

I would like to read an output command line per line. For this I use the StdoutPipe method and the bufio library:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "os/exec"
  7. "bufio"
  8. )
  9. func main() {
  10. cmd := exec.Command("printf", "{\"Name\": \"Bob\", \"Age\": 1}\n%.0s", "{1..5}")
  11. stdout, err := cmd.StdoutPipe()
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. scanner := bufio.NewScanner(stdout)
  16. if err := cmd.Start(); err != nil {
  17. log.Fatal(err)
  18. }
  19. var person struct {
  20. Name string
  21. Age int
  22. }
  23. for scanner.Scan() {
  24. if err := json.Unmarshal([]byte(scanner.Text()), &person); err != nil {
  25. log.Fatal(err)
  26. } else {
  27. fmt.Printf("%s is %d years old\n", person.Name, person.Age)
  28. }
  29. }
  30. if err := cmd.Wait(); err != nil {
  31. log.Fatal(err)
  32. }
  33. }

I should obtain 5 lines:

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

The point is that I only get the first line. I am quite new on Goand I guess the usage of the StdoutPipe is incorrect.

答案1

得分: 1

{1..5}在shell中被展开为1 2 3 4 5,所以你必须自己完成这个操作:

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

另外请注意使用原始字符串,它比不断转义所有内容更方便。另外,与此相关的是,你应该真正使用scanner.Bytes()而不是[]byte(scanner.Text())

英文:

{1..5} is expanded to 1 2 3 4 5 by the shell, so you must do it yourself:

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

Also note the use of raw strings, its much more convenient than constantly escaping everything. And on a related note, instead of []byte(scanner.Text()) you should really use scanner.Bytes().

huangapple
  • 本文由 发表于 2016年2月5日 18:16:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/35221537.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定