命令 StdinPipe 过早关闭

我一直在尝试pg_restore使用数据库转储文件中的数据 来调用exec.Command和提供数据,它适用于 1Mb 以下的小文件,但对于较大的转储,它会因错误而失败。我还尝试逐行扫描并写入管道,但它导致了相同的错误,并且像在单独的 goroutine 中一样运行也无济于事。StdinPipewrite |1: broken pipecmd.Run()


去:1.14 操作系统:macOS


cmd := exec.Command("pg_restore", "--clean", "-n public", "--dbname=DB_URI")

cmd.Stdout = os.Stdout

cmd.Stderr = os.Stderr

pw, err := cmd.StdinPipe()

defer pw.Close()

...


done := make(chan struct{})

errCh := make(chan error)

file, err := os.Open("dumpfile")

defer file.Close()


if err := cmd.Start(); err != nil {

    return err

}


_, err = io.Copy(pw, file)


我做错了什么或如何保持管道畅通?


Helenr
浏览 159回答 3
3回答

交互式爱情

包括cmd.Wait()应该解决您的问题,就像您的评论之一说的那样。

RISEBY

使用cat代替时pg_restore,您的代码有效。另一方面,在使用时,我遇到了与您相同的错误,这实际上是预期的。head -10由于您是cmd在异步模式下启动的,因此如果pg_restore在使用它的所有之前停止,如果它尝试在封闭的管道上写入STDIN,io.Copy则会遇到这种错误。检查您的pg_restore命令的状态(最终返回码、打印在其 STDERR 上的内容、日志...)以查看是否存在实际错误。您可以将此错误视为您不应再向此命令提供输入的正常指示。

一只甜甜圈

在我同事的帮助下,我们发现命令参数格式错误,因为 Go 直接使用系统调用,程序的每个参数都必须是单独的,所以这 -n public导致了问题"pg_restore", "--clean", "-n public", "--dbname=DB_URI"并且修复也很清楚 - 拆分它们-n,public"pg_restore", "--clean", "-n", "public", "--dbname=DB_URI"
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go