英文:
Goland reading liner per line output of a command
问题
我想逐行读取输出命令。为此,我使用了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
的使用方法不正确。
英文:
I would like to read an output command line per line. For this I use the StdoutPipe
method and the bufio
library:
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)
}
}
I should obtain 5 lines:
$ 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}
The point is that I only get the first line. I am quite new on Go
and I guess the usage of the StdoutPipe is incorrect.
答案1
得分: 1
{1..5}
在shell中被展开为1 2 3 4 5
,所以你必须自己完成这个操作:
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:
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()
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论