Go exec.Command(…).Wait()永远挂起的问题

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

Go exec.Command(...).Wait() hangs for ever

问题

大家好,由于某种原因,当我执行mysql命令时,Wait()函数会永远挂起,有人知道为什么吗?
以下是我的代码:

// 将数据导入本地数据库
func (x MySQL) Import(data string, opt LocalDb) {
var stderr bytes.Buffer
cmd := exec.Command("mysql", x.importOptions(opt)...)
// 设置<管道变量
stdin, err := cmd.StdinPipe()
errChk(err)

cmd.Stderr = &stderr
cmd.Start()

// 将数据写入管道
io.WriteString(stdin, data)
fmt.Println("正在导入" + x.DB + "到本地...")

// 记录mysql错误
if err := cmd.Wait(); err != nil {
    log.Fatal(stderr.String())
} else {
    fmt.Println("导入完成")
}

}

这个函数完成了所有操作,mysql将数据导入数据库,但它永远不会从Wait()函数中返回,即使已经完成。

英文:

Hi guys for some reason Wait() when I execute mysql command hangs for ever, does anyone know why?
Here is my code.

// Import imports data into Local database
func (x MySQL) Import(data string, opt LocalDb) {
	var stderr bytes.Buffer
	cmd := exec.Command(&quot;mysql&quot;, x.importOptions(opt)...)
	// Set &lt; pipe variable
	stdin, err := cmd.StdinPipe()
	errChk(err)

	cmd.Stderr = &amp;stderr
	cmd.Start()

	// Write data to pipe
	io.WriteString(stdin, data)
	fmt.Println(&quot;Importing &quot; + x.DB + &quot; to localhost...&quot;)

	// Log mysql error
	if err := cmd.Wait(); err != nil {
		log.Fatal(stderr.String())
	} else {
		fmt.Println(&quot;Importing complete&quot;)
	}
}

This function accomplishes everything and mysql imports the data into database but it never return from Wait() just freezes there even though is completed.

答案1

得分: 3

问题在于您没有关闭stdin管道。MySQL将保持活动状态,直到关闭该管道。

修复方法很简单:

// 将数据写入管道
io.WriteString(stdin, data)
stdin.Close()
fmt.Println("将" + x.DB + "导入到本地主机...")

StdinPipe()的行为如下所述:

StdinPipe返回一个管道,该管道在命令启动时将连接到命令的标准输入。*在Wait看到命令退出后,该管道将自动关闭。调用者只需调用Close来更早地强制关闭管道。*例如,如果运行的命令直到标准输入关闭后才退出,则调用者必须关闭该管道。

英文:

The problem is that you haven't closed the stdin pipe. MySQL will remain active until it is.

The fix is thus simple:

// Write data to pipe
io.WriteString(stdin, data)
stdin.Close()
fmt.Println(&quot;Importing &quot; + x.DB + &quot; to localhost...&quot;)

The fact that StdinPipe() acts in this way is documented as such:

> StdinPipe returns a pipe that will be connected to the command's standard input when the command starts. The pipe will be closed automatically after Wait sees the command exit. A caller need only call Close to force the pipe to close sooner. For example, if the command being run will not exit until standard input is closed, the caller must close the pipe.

huangapple
  • 本文由 发表于 2016年11月20日 03:38:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/40697126.html
匿名

发表评论

匿名网友

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

确定