我想做一些类似 unix 的东西tail -f,但是在通过 Go 的Cmd设施运行的进程产生的输出上。
显然,我的 google-fu 没有达到标准,但我确实找到了这篇文章,它引导我编写以下代码,几乎可以正常工作,但我希望能得到帮助。
如果重要的话,我会在 Mac 上运行它。
首先,这是编译为slowroll可执行文件的最小程序:
package main
import (
"fmt"
"time"
)
func main() {
line := 1
for {
fmt.Println("This is line", line)
line += 1
time.Sleep(2 * time.Second)
}
}
运行时,它会产生以下输出,每 2 秒一行:
> ./slowroll
This is line 1
This is line 2
This is line 3
This is line 4
等等。
这是尝试读取此内容的包代码,但允许超时以便可以完成其他操作:
package timeout_io
import (
"bufio"
"bytes"
"context"
"errors"
"time"
)
const BufferSize = 4096
var ErrTimeout = errors.New("timeout")
type TimeoutReader struct {
b *bufio.Reader
t time.Duration
}
func NewTimeoutReader(stdOut *bytes.Buffer) *TimeoutReader {
return &TimeoutReader{b: bufio.NewReaderSize(stdOut, BufferSize), t: 0}
}
func (r *TimeoutReader) SetTimeout(t time.Duration) time.Duration {
prev := r.t
r.t = t
return prev
}
type CallResponse struct {
Resp string
Err error
}
func helper(r *bufio.Reader) <-chan *CallResponse {
respChan := make(chan *CallResponse, 1)
go func() {
resp, err := r.ReadString('\n')
if err != nil {
respChan <- &CallResponse{resp, err}
} else {
respChan <- &CallResponse{resp, nil}
}
return
}()
return respChan
}
func (r *TimeoutReader) ReadLineCtx(ctx context.Context) (string, error) {
select {
case <-ctx.Done():
return "", ErrTimeout
case respChan := <-helper(r.b):
return respChan.Resp, respChan.Err
}
}
慕姐4208626
一只斗牛犬
缥缈止盈
相关分类