无法捕获 cmd.Run() 的标准输出(stdout),但标准错误(stderr)是正常的。

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

Can't capture cmd.Run() stdout, stderr is fine

问题

这是一个简单的Python脚本,每秒生成两个stdout/stderr消息。

  1. #!/usr/bin/env python3
  2. import sys, time
  3. for a in range(10):
  4. if(a%2==0): print(a, file=sys.stdout)
  5. else: print(a, file=sys.stderr)
  6. time.sleep(0.5)
  7. print("This is an STDOUT message")
  8. print("This is an STDERR message", file=sys.stderr)
  9. sys.exit(1)

示例输出:

  1. > ./runstatus.py
  2. 0 <- STDOUT0.5秒后
  3. 1 <- STDERR0.5秒后
  4. 2 <- STDOUT0.5秒后
  5. 3 ...
  6. 4
  7. 5
  8. 6
  9. 7
  10. 8
  11. 9
  12. This is an STDOUT message <- STDOUT
  13. This is an STDERR message <- STDERR

我需要使用Golang实时捕获stdout和stderr输出,所以我找到了下面这段代码:

  1. package main
  2. import("bufio"; "fmt"; "os/exec";)
  3. func readerr(scanner *bufio.Scanner, channel string) {
  4. for scanner.Scan() { fmt.Println(channel, scanner.Text()); }
  5. }
  6. func main() {
  7. cmd:=exec.Command("./runstatus.py")
  8. stdout, _:=cmd.StdoutPipe()
  9. stderr, _:=cmd.StderrPipe()
  10. scanout:=bufio.NewScanner(stdout)
  11. scanerr:=bufio.NewScanner(stderr)
  12. scanout.Split(bufio.ScanLines)
  13. scanerr.Split(bufio.ScanLines)
  14. go readerr(scanout, "out:")
  15. go readerr(scanerr, "err:")
  16. cmd.Start()
  17. cmd.Wait()
  18. }

但问题是它只能处理STDERR! STDERR实时输出,但STDOUT不是,它在执行结束时突然输出:

  1. err: 1 <- STDERR1秒后
  2. err: 3 <- STDERR1秒后
  3. err: 5
  4. err: 7
  5. err: 9
  6. out: 0 <- STDOUT5秒后,从这里开始,其余的输出都突然刷新!
  7. out: 2
  8. out: 4
  9. out: 6
  10. out: 8
  11. out: This is an STDOUT message
  12. err: This is an STDERR message

我做错了什么?

英文:

This simple python script generates stdout/stderr messages, two per second.

  1. #!/usr/bin/env python3
  2. import sys, time
  3. for a in range(10):
  4. if(a%2==0): print(a, file=sys.stdout)
  5. else: print(a, file=sys.stderr)
  6. time.sleep(0.5)
  7. print(&quot;This is an STDOUT message&quot;)
  8. print(&quot;This is an STDERR message&quot;, file=sys.stderr)
  9. sys.exit(1)

Example output:

  1. &gt; ./runstatus.py
  2. 0 &lt;- STDOUT, after 0.5s
  3. 1 &lt;- STDERR, after 0.5s
  4. 2 &lt;- STDOUT, after 0.5s
  5. 3 ...
  6. 4
  7. 5
  8. 6
  9. 7
  10. 8
  11. 9
  12. This is an STDOUT message &lt;- STDOUT
  13. This is an STDERR message &lt;- STDERR

I need to capture the stdout and stderr outputs in realtime with golang, so I found moreover this:

  1. package main
  2. import(&quot;bufio&quot;; &quot;fmt&quot;; &quot;os/exec&quot;;)
  3. func readerr(scanner *bufio.Scanner, channel string) {
  4. for scanner.Scan() { fmt.Println(channel, scanner.Text()); }
  5. }
  6. func main() {
  7. cmd:=exec.Command(&quot;./runstatus.py&quot;)
  8. stdout, _:=cmd.StdoutPipe()
  9. stderr, _:=cmd.StderrPipe()
  10. scanout:=bufio.NewScanner(stdout)
  11. scanerr:=bufio.NewScanner(stderr)
  12. scanout.Split(bufio.ScanLines)
  13. scanerr.Split(bufio.ScanLines)
  14. go readerr(scanout, &quot;out:&quot;)
  15. go readerr(scanerr, &quot;err:&quot;)
  16. cmd.Start()
  17. cmd.Wait()
  18. }

But the problem is this just works with STDERR!!! Stderr goes in realtime, but stdout not, it bumps suddenly at the end of the execution:

  1. err: 1 &lt;- STDERR, after 1s
  2. err: 3 &lt;- STDERR, after 1s
  3. err: 5
  4. err: 7
  5. err: 9
  6. out: 0 &lt;- STDOUT, after 5s, from here, the rest just flushes abruptly!
  7. out: 2
  8. out: 4
  9. out: 6
  10. out: 8
  11. out: This is an STDOUT message
  12. err: This is an STDERR message

What am I doing wrong?

答案1

得分: 3

可能的问题是,在Python中,print输出到标准输出(stdout)是有缓冲的。解决方案可能取决于Python的版本。

例如,可以使用-u选项运行脚本:

  1. python -u ./runstatus.py

自Python 3.3起,print函数有一个flush参数,你可以尝试使用它:

  1. print(a, file=sys.stdout, flush=True)
英文:

Probably the problem is that in Python the print output to stdout is buffered. The solution may depend on the Python version.

For example, run a script with the -u option

  1. python -u ./runstatus.py

Since Python 3.3, the print function has a flash parameter, you can try using it:

  1. print(a, file=sys.stdout, flush=True)

huangapple
  • 本文由 发表于 2022年10月23日 21:14:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/74171437.html
匿名

发表评论

匿名网友

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

确定