为了账号安全,请及时绑定邮箱和手机立即绑定

从 cmd.StdoutPipe() 读取

从 cmd.StdoutPipe() 读取

Go
POPMUISE 2022-06-21 16:26:50
请考虑这个 Go 代码:package mainimport (    "fmt"    "os/exec"    "strings"    "time")const (    debugCmd = "/usr/bin/libinput debug-events"    //debugCmd = "tail -f /tmp/syslog")func main() {    fmt.Println("Hello!")    fmt.Println("cmd", debugCmd)    cmdSplat := strings.Split(debugCmd, " ")    cmd := exec.Command(cmdSplat[0], cmdSplat[1:]...)    stdOut, err := cmd.StdoutPipe()    if err != nil {        fmt.Println("cmd.StdOut failed", err)    }    defer stdOut.Close()    go func() {        tempBuf := make([]byte, 1024)        for {            n, err := stdOut.Read(tempBuf)            if n > 0 {                fmt.Printf("Read: %d bytes, err: %v\n", n, err)                someSlice := tempBuf[:n]                fmt.Println("text", string(someSlice))            } else {                fmt.Printf("Zero Read :%d, err: %v", n, err)            }        }    }()    fmt.Println("STarting cmd")    err = cmd.Start()    if err != nil {        fmt.Println("cmd.start", err)    }    fmt.Println("All done!")    // cmd.Wait()    time.Sleep(60 * time.Second)    fmt.Println("Done sleeping!")}在现实生活中,它只有在读取 1024 个字节后才会恢复。早些时候我使用 bufio 进行了此操作,但这也很慢:go func() {    r := bufio.NewReader(stdOut)    for {        line, err := r.ReadString('\n')        if err != nil {            fmt.Println("End of things!")            break        }        fmt.Print(line)    }}()我的目标是debug-events从stdOut io.ReadCloser相当快的速度——当它们发生和出现时——而不是水印为 1024 字节的批次。这是我的输出:Read: 1024 bytes, err: <nil> // <------------ this text finger) event5   POINTER_AXIS     +2.380s  vert -11.14/0* horiz 10.75/0* (finger) event5   POINTER_AXIS     +2.400s  vert -8.97/0* horiz 6.54/0* (finger) <snip> event5   POINTER_AXIS     +3.219s  vert 7.42/0* horiz 0.00/0 (finger) event5   POINTER_AXIS Read: 1024 bytes, err: <nil> // <-------------- this text     +3.238s    vert 9.28/0* horiz -15.89/0* (finger)你能指点我正确的方法吗?
查看完整描述

1 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

正如评论中所讨论的,这根本不是 Go 问题,而只是需要在 GNU/Linux 系统上使用stdbuf命令。另请参阅此 unix.stackexchange.com 问题和答案。一般的想法是确保您运行的程序exec.Command不会不恰当地缓冲自己的输出。

(stdbuf 程序通常用于LD_PRELOAD为 stdin、stdout 和 stderr 插入替代 I/O 缓冲,或者可以内置到操作系统上的标准库中。)


查看完整回答
反对 回复 2022-06-21
  • 1 回答
  • 0 关注
  • 308 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号