命令 StdinPipe 关闭得太早
Command StdinPipe closes too soon
我一直在尝试使用 exec.Command
调用 pg_restore
并向 StdinPipe
提供来自数据库转储文件的数据,它适用于 1Mb 以下的小文件,但无法处理更大的转储出现 write |1: broken pipe
错误。我还尝试逐行扫描并写入管道,但它导致了相同的错误,并且 运行 像 cmd.Run()
在单独的 goroutine 中也没有帮助。
进行:1.14
OS: 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)
我做错了什么或如何保持管道畅通?
当使用 cat
而不是 pg_restore
时,您的代码有效。
另一方面,当使用 head -10
时,我遇到了与您相同的错误,这实际上是预期的。
由于您是在异步模式下启动 cmd
,如果 pg_restore
在消耗完其所有 STDIN
之前停止,io.Copy
将遇到此类错误尝试在封闭的管道上写入。
检查您的 pg_restore
命令的状态(最终 return 代码、打印在其 STDERR 上的内容、日志...)以查看是否存在实际错误。
您可以将此错误视为您不应再向此命令提供输入的正常指示。
包括 cmd.Wait()
应该可以解决您的问题,就像您的评论之一中所说的那样。
在我同事的帮助下,我们发现命令参数格式不正确,因为 Go 直接使用系统调用,程序的每个参数必须分开,所以这里
-n public
导致了问题
"pg_restore", "--clean", "-n public", "--dbname=DB_URI"
并且修复也很清楚 – 拆分它们 -n
、public
"pg_restore", "--clean", "-n", "public", "--dbname=DB_URI"
我一直在尝试使用 exec.Command
调用 pg_restore
并向 StdinPipe
提供来自数据库转储文件的数据,它适用于 1Mb 以下的小文件,但无法处理更大的转储出现 write |1: broken pipe
错误。我还尝试逐行扫描并写入管道,但它导致了相同的错误,并且 运行 像 cmd.Run()
在单独的 goroutine 中也没有帮助。
进行:1.14 OS: 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)
我做错了什么或如何保持管道畅通?
当使用 cat
而不是 pg_restore
时,您的代码有效。
另一方面,当使用 head -10
时,我遇到了与您相同的错误,这实际上是预期的。
由于您是在异步模式下启动 cmd
,如果 pg_restore
在消耗完其所有 STDIN
之前停止,io.Copy
将遇到此类错误尝试在封闭的管道上写入。
检查您的 pg_restore
命令的状态(最终 return 代码、打印在其 STDERR 上的内容、日志...)以查看是否存在实际错误。
您可以将此错误视为您不应再向此命令提供输入的正常指示。
包括 cmd.Wait()
应该可以解决您的问题,就像您的评论之一中所说的那样。
在我同事的帮助下,我们发现命令参数格式不正确,因为 Go 直接使用系统调用,程序的每个参数必须分开,所以这里
-n public
导致了问题
"pg_restore", "--clean", "-n public", "--dbname=DB_URI"
并且修复也很清楚 – 拆分它们 -n
、public
"pg_restore", "--clean", "-n", "public", "--dbname=DB_URI"