Как перенаправить команду в Go без вывода результата в Терминал?

Я хочу запустить команду: pbcopy < file.csv в моей программе Go. Однако похоже, что пакет Go os/exec не может перенаправлять одну команду на другую, используя синтаксис <. Поэтому я решил использовать канал в своей программе. Однако этот скрипт:

package main

import (
    "os/exec"
)

func main() {
    cmd1 := exec.Command("cat", "test.csv")
    cmd2 := exec.Command("pbcopy")
    out, _ := cmd1.StdoutPipe()
    cmd2.Stdin = out
    cmd2.Run()
}

Когда я запускаю указанную выше программу, она не завершается и выглядит так, будто ждет ввода от пользователя в Терминале. И когда я завершаю его и пытаюсь вставить результат куда угодно, он не принимает ввод и сохраняет его в буфер обмена.

Затем я меняю последнюю строку программы с cmd2.Run() на cmd2.Start(), после чего программа корректно завершается. Однако буфер обмена заполнен пустой строкой и не сохраняет вывод cat file.csv в буфер обмена.

Я попытался найти несколько примеров использования канала в os.exec в Go, но все, что я видел, предполагает, что результат выводится в терминал в конце, например ls -l | wc -l или ls -l | grep "py" или что-то в этом роде. Но команда pbcopy не отображает ввод, а просто сохраняет ввод в буфер обмена.

Итак, как я могу использовать перенаправление (или канал) в пакете os.exec в Go с командой pbcopy?


person Blaszard    schedule 28.04.2014    source источник


Ответы (1)


Вам нужно запустить команду 1. Команда 2 ожидает ввода от команды 1 и, вероятно, будет ждать бесконечно долго.

cmd1.Start()
cmd2.Run()

EDIT: оглядываясь назад на вопрос, почему вы делаете это как две команды? Вместо этого вы можете os.Open("test.csv") и передать указатель файла непосредственно cmd2.Stdin.

person Stephen Weinberg    schedule 28.04.2014
comment
Спасибо. Нужно ли также вызывать cmd1.Wait()? Или, может быть, cmd2.Run() автоматически ждет, пока cmd1 завершит свою задачу, как только я установлю cmd2.Stdin? - person Blaszard; 28.04.2014
comment
cmd2 заканчивается, когда захочется. Вероятно, он ожидает EOF от cmd1. В зависимости от вашей ситуации может иметь смысл убить cmd1, если он все еще не завершился. - person Stephen Weinberg; 28.04.2014