【发布时间】:2021-12-25 12:17:02
【问题描述】:
谁能帮忙?
我有一个正在通过 exec.CommandContext 运行的应用程序(所以我可以通过 ctx 取消它)。除非出错,否则它通常不会停止。
我目前让它将其输出中继到 os.stdOut,它运行良好。但我也想通过一个通道获取每一行 - 这背后的想法是我将在该行上查找一个正则表达式,如果它为真,那么我将设置一个“错误”的内部状态。
虽然我无法让它工作,但我尝试了 NewSscanner。这是我的代码。
正如我所说,它确实会输出到 os.StdOut,这很棒,但我希望接收在我设置的频道中发生的每一行。
有什么想法吗?
提前致谢。
func (d *Daemon) Start() {
ctx, cancel := context.WithCancel(context.Background())
d.cancel = cancel
go func() {
args := "-x f -a 1"
cmd := exec.CommandContext(ctx, "mydaemon", strings.Split(args, " ")...)
var stdoutBuf, stderrBuf bytes.Buffer
cmd.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
cmd.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
lines := make(chan string)
go func() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
fmt.Println("I am reading a line!")
lines <- scanner.Text()
}
}()
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
select {
case outputx := <-lines:
// I will do somethign with this!
fmt.Println("Hello!!", outputx)
case <-ctx.Done():
log.Println("I am done!, probably cancelled!")
}
}()
}
也试过用这个
go func() {
scanner := bufio.NewScanner(&stdoutBuf)
for scanner.Scan() {
fmt.Println("I am reading a line!")
lines <- scanner.Text()
}
}()
即便如此,“我正在阅读一行”永远不会出现,我也对其进行了调试,它从未进入“用于扫描仪..”
还尝试扫描&stderrBuf,同样,没有任何输入。
【问题讨论】:
-
您正在扫描 os.Stdin 而不是 stdout buf
-
谢谢,是的,我也这么认为,但我之前尝试过,但没有成功。刚刚又试了一次。
-
更新了主要问题以包含该问题。
-
两个不同的人建议@IanGregson,几乎只是写了同样的东西。是时候将问题的最小、可执行的再现放入问题中,这样我们就可以用更好的信息来支持我们的答案。
-
(1) 命令输出到
stdoutBuf,而不是os.Stdin。 (2) 从stdoutBuf读取的程序版本在缓冲区存在数据竞争。通过使用管道而不是缓冲区来修复。 (3) 你可能想要一个围绕 select 语句的循环。