英文:
Can't capture cmd.Run() stdout, stderr is fine
问题
这是一个简单的Python脚本,每秒生成两个stdout/stderr消息。
#!/usr/bin/env python3
import sys, time
for a in range(10):
if(a%2==0): print(a, file=sys.stdout)
else: print(a, file=sys.stderr)
time.sleep(0.5)
print("This is an STDOUT message")
print("This is an STDERR message", file=sys.stderr)
sys.exit(1)
示例输出:
> ./runstatus.py
0 <- STDOUT,0.5秒后
1 <- STDERR,0.5秒后
2 <- STDOUT,0.5秒后
3 ...
4
5
6
7
8
9
This is an STDOUT message <- STDOUT
This is an STDERR message <- STDERR
我需要使用Golang实时捕获stdout和stderr输出,所以我找到了下面这段代码:
package main
import("bufio"; "fmt"; "os/exec";)
func readerr(scanner *bufio.Scanner, channel string) {
for scanner.Scan() { fmt.Println(channel, scanner.Text()); }
}
func main() {
cmd:=exec.Command("./runstatus.py")
stdout, _:=cmd.StdoutPipe()
stderr, _:=cmd.StderrPipe()
scanout:=bufio.NewScanner(stdout)
scanerr:=bufio.NewScanner(stderr)
scanout.Split(bufio.ScanLines)
scanerr.Split(bufio.ScanLines)
go readerr(scanout, "out:")
go readerr(scanerr, "err:")
cmd.Start()
cmd.Wait()
}
但问题是它只能处理STDERR! STDERR实时输出,但STDOUT不是,它在执行结束时突然输出:
err: 1 <- STDERR,1秒后
err: 3 <- STDERR,1秒后
err: 5
err: 7
err: 9
out: 0 <- STDOUT,5秒后,从这里开始,其余的输出都突然刷新!
out: 2
out: 4
out: 6
out: 8
out: This is an STDOUT message
err: This is an STDERR message
我做错了什么?
英文:
This simple python script generates stdout/stderr messages, two per second.
#!/usr/bin/env python3
import sys, time
for a in range(10):
if(a%2==0): print(a, file=sys.stdout)
else: print(a, file=sys.stderr)
time.sleep(0.5)
print("This is an STDOUT message")
print("This is an STDERR message", file=sys.stderr)
sys.exit(1)
Example output:
> ./runstatus.py
0 <- STDOUT, after 0.5s
1 <- STDERR, after 0.5s
2 <- STDOUT, after 0.5s
3 ...
4
5
6
7
8
9
This is an STDOUT message <- STDOUT
This is an STDERR message <- STDERR
I need to capture the stdout and stderr outputs in realtime with golang, so I found moreover this:
package main
import("bufio"; "fmt"; "os/exec";)
func readerr(scanner *bufio.Scanner, channel string) {
for scanner.Scan() { fmt.Println(channel, scanner.Text()); }
}
func main() {
cmd:=exec.Command("./runstatus.py")
stdout, _:=cmd.StdoutPipe()
stderr, _:=cmd.StderrPipe()
scanout:=bufio.NewScanner(stdout)
scanerr:=bufio.NewScanner(stderr)
scanout.Split(bufio.ScanLines)
scanerr.Split(bufio.ScanLines)
go readerr(scanout, "out:")
go readerr(scanerr, "err:")
cmd.Start()
cmd.Wait()
}
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:
err: 1 <- STDERR, after 1s
err: 3 <- STDERR, after 1s
err: 5
err: 7
err: 9
out: 0 <- STDOUT, after 5s, from here, the rest just flushes abruptly!
out: 2
out: 4
out: 6
out: 8
out: This is an STDOUT message
err: This is an STDERR message
What am I doing wrong?
答案1
得分: 3
可能的问题是,在Python中,print
输出到标准输出(stdout)是有缓冲的。解决方案可能取决于Python的版本。
例如,可以使用-u选项运行脚本:
python -u ./runstatus.py
自Python 3.3起,print
函数有一个flush
参数,你可以尝试使用它:
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
python -u ./runstatus.py
Since Python 3.3, the print
function has a flash
parameter, you can try using it:
print(a, file=sys.stdout, flush=True)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论