使用exec.Command时,我应该在使用StdoutPipe时等待命令吗?

问题描述 投票:1回答:1

我正在构建一个供个人使用的小型音频应用程序,需要通过管道连接到某些外部工具。

我想围绕io.ReadCloser构建程序,然后将其转换并通过管道传输到PulseAudios paplay命令。

一个简化的示例:

package main

import (
  "os/exec"
)

func main () {
  speech, err := Say("Hello world!")
  if err != nil {
    log.Fatal(err)
  }

  err = Play(speech)
  if err != nil {
    log.Fatal(err)
  }
}

// Say creates a stream containing text as a text-to-speech wav audio stream.
func Say(text string) (io.ReadCloser, error) {
  speak := exec.Command("espeak", "--stdout", text)

  out, err := speak.StdoutPipe()
  if err != nil {
    return nil, err
  }

  return out, speak.Start()
}

// Play a wav audio stream.
func Play(s io.ReadCloser) error {
  play := exec.Command("paplay")

  play.Stdin = s
  play.Stderr = os.Stderr

  return play.Run()
}

这是一个简化的示例,但是我想使用不同的命令来创建wav流,并将它们连接起来并通过管道传递到paplay

exec.Cmd上的go docs指定我需要在每个命令上调用exec.Cmd以确保清除分配给运行该命令的资源:

等待释放与Cmd相关的任何资源。

但是同时不清楚在使用Wait时是否需要调用此。

stdout管道用完并且命令退出后,将清理命令吗?还是需要在这里重新考虑抽象?

go stream pipe exec
1个回答
0
投票

但是同时不清楚在使用StdoutPipe时是否需要调用它。

是,您仍然需要StdoutPipe来考虑cmd实例完全结束。

但是,通过管道传输标准输出流,其关闭信号足以检测复制结束。

医生说

StdoutPipe返回将连接到命令的管道的管道。命令启动时的标准输出。

等待命令退出后将关闭管道,因此大多数呼叫者不需要自己关闭管道;但是,这意味着在管道中的所有读取之前调用“等待”是不正确的完成。由于相同的原因,使用时调用Run是不正确的StdoutPipe。请参阅示例以了解惯用用法。


在stdout管道用完并且命令退出后将清理命令或

是。

我需要在这里重新思考我的抽象吗?

编号

您的代码还可以。

© www.soinside.com 2019 - 2024. All rights reserved.