Я пишу программу на Go, которая выполняет серверную программу (также Go). Теперь я хочу иметь стандартный вывод дочерней программы в окне терминала, в котором я запустил родительскую программу. Один из способов сделать это - использовать cmd.Output()
функцию, но она выводит стандартный вывод только после выхода из процесса. (Это проблема, потому что эта серверная программа работает долгое время, и я хочу прочитать вывод журнала)
Переменная out
имеет значение, type io.ReadCloser
и я не знаю, что мне делать с ней для выполнения моей задачи, и я не могу найти в Интернете ничего полезного по этой теме.
func main() {
cmd := exec.Command("/path/to/my/child/program")
out, err := cmd.StdoutPipe()
if err != nil {
fmt.Println(err)
}
err = cmd.Start()
if err != nil {
fmt.Println(err)
}
//fmt.Println(out)
cmd.Wait()
}
Пояснение к коду: раскомментируйте Println
функцию, чтобы код компилировался, я знаю, что Println(out io.ReadCloser)
это бессмысленная функция.
(выводит результат &{3 |0 <nil> 0}
) Эти две строчки нужны только для компиляции кода.
io.Copy
в подпрограммах gocmd.Wait()
илиfor{}
зацикливаться ... почему они здесь?Ответы:
Не нужно возиться с трубами или горутинами, это просто.
источник
cmd.Stdin = os.Stdin
таким образом, как будто вы буквально выполнили эту команду из своей оболочки.log
вместо stdout, есть ответ здесьЯ считаю , что если импортировать
io
иos
заменить это:с этим:
(см. документацию для
io.Copy
и дляos.Stdout
), он будет делать то, что вы хотите. (Отказ от ответственности: не проверено.)Кстати, вы, вероятно, захотите зафиксировать и стандартную ошибку, используя тот же подход, что и для стандартного вывода, но с помощью
cmd.StderrPipe
иos.Stderr
.источник
os.Stdout
) и (2) подтверждение предположения о том, что, если вы вообще не вызываетеcmd.StdoutPipe()
, стандартный вывод идет к стандартному выводу/dev/null
родительского процесса, а не к нему. .Для тех, кому это не нужно в цикле, но хотелось бы, чтобы вывод команды выводился на терминал без
cmd.Wait()
блокировки других операторов:источник