Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 正在从“exec.Cmd`in”获取输出;“实时”;_Go_Exec_Stdout_Buffering - Fatal编程技术网

Go 正在从“exec.Cmd`in”获取输出;“实时”;

Go 正在从“exec.Cmd`in”获取输出;“实时”;,go,exec,stdout,buffering,Go,Exec,Stdout,Buffering,这个问题与类似,只是它与exec命令的输出缓冲有关 我有以下测试程序: package main import ( "fmt" "log" "os/exec" ) func main() { cmd := exec.Command("python", "inf_loop.py") var out outstream cmd.Stdout = out if err := cmd.Start(); err != nil {

这个问题与类似,只是它与
exec
命令的输出缓冲有关

我有以下测试程序:

package main

import (
    "fmt"
    "log"
    "os/exec"
)

func main() {
    cmd := exec.Command("python", "inf_loop.py")
    var out outstream
    cmd.Stdout = out
    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }
    fmt.Println(cmd.Wait())
}

type outstream struct{}

func (out outstream) Write(p []byte) (int, error) {
    fmt.Println(string(p))
    return len(p), nil
}
上面提到的inf_loop.py,只包含:

print "hello"
while True:
    pass
go程序在我运行时挂起,不输出任何内容,但是如果我使用
os.Stdout
而不是
out
,那么它会在挂起之前输出“hello”。为什么这两个io.Writer之间存在差异?如何解决

更多诊断信息:

  • inf\u loop.py
    中删除循环时,两个程序都会输出“hello”,正如预期的那样
  • 当使用
    yes
    作为程序而不是python脚本,并在
    outstream.Write中输出
    len(p)
    时,就会有输出,输出通常是16384或32768。这向我表明,正如我最初预期的那样,这是一个缓冲问题,但我仍然不理解为什么
    outstream
    结构被缓冲阻止,而
    os.Stdout
    没有。一种可能性是,该行为是
    exec
    io.Writer
    直接传递到
    os.StartProcess
    的方式的结果,如果它是
    os.File
    (请参阅以获取详细信息),否则它会在进程和
    io.Writer
    之间创建一个
    os.Pipe(),这条管道可能会导致缓冲。但是,
    os.Pipe()
    的操作和可能的缓冲级别太低,我无法进行调查

默认情况下Python缓冲区标准输出。尝试以下程序:

import sys
print "hello"
sys.stdout.flush()
while True:
    pass
或者使用无缓冲的stdout和stderr运行Python:

cmd := exec.Command("python", "-u", "foo.py")
注意-u标志


使用
cmd.Stout=os.Stdout时会看到不同的结果,因为当Stdout是终端时Python使用行缓冲。

完美的答案,谢谢!仅供将来参考,我很好奇Python是如何知道在后一种情况下stdout是一个终端的,并发现一般的方法是使用。顺便说一句,Linux(实际上是GNU coreutils)和FreeBSD(可能还有其他)有
stdbuf
,它改变了任意命令的初始缓冲。对于没有选项的命令(如此处显示的
-u
,或grep的
--line buffered
)非常有用。