Стоит ли ждать команды при использовании StdoutPipe при использовании exec.Command? - PullRequest
1 голос
/ 16 октября 2019

Я создаю небольшое аудио-приложение для личного использования, и мне нужно подключиться к некоторым внешним инструментам.

Я хочу структурировать свою программу вокруг io.ReadCloser s, которую я преобразую, и передать в PulseAudios paplay command.

Упрощенный пример:

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.

Документы go на exec.Cmd указывают, что мне нужно вызывать Wait для каждой команды, чтобы убедиться, что ресурсы, выделенные для выполнения команды, очищены:

Wait освобождает любые ресурсы, связанные с Cmd.

Но в то же время неясно, нужно ли мне вызывать это при использовании StdoutPipe.

Удастся ли очистить команду после исчерпания канала stdout и выхода из команды, или мне нужно переосмыслить мои абстракции здесь?

1 Ответ

0 голосов
/ 16 октября 2019

Но в то же время неясно, нужно ли мне вызывать это при использовании StdoutPipe.

Да, вам все еще нужно Wait(), чтобы считать экземпляры cmd полностью завершенными.

Однако, чтобы передать поток stdout, его сигнал закрытия достаточен для определения конца копии.

Документ говорит:

StdoutPipe возвращает канал, который будет подключен кстандартный вывод команды при ее запуске.

Ожидание закроет канал после просмотра команды выхода , поэтому большинству вызывающих абонентов нет необходимости закрывать канал самостоятельно;однако подразумевается, что некорректно вызывать Wait до завершения всех чтений из канала. По той же причине некорректно вызывать Run при использовании StdoutPipe. См. Пример для идиоматического использования.


Пройдет команду очистки после того, как канал stdout исчерпан и команда завершилась или

yes.

мне нужно переосмыслить мои абстракции здесь?

нет.

ваш код в порядке.

...