exec.Cmd.StdoutPipe

Метод StdoutPipe создает канал (pipe), который соединяет стандартный вывод команды с файлом io.ReadCloser в вашей Go-программе. Это позволяет читать вывод команды по мере его поступления, не дожидаясь завершения команды. Метод должен быть вызван до запуска команды с помощью Start или Run.

Синтаксис

gocmd := exec.Command("command", "arg1", "arg2")
stdout, err := cmd.StdoutPipe()

Пример

Давайте получим вывод команды echo через канал:

gopackage main

import (
  "bufio"
  "fmt"
  "os/exec"
)

func main() {
  cmd := exec.Command("echo", "Hello, Go!")
  stdout, err := cmd.StdoutPipe()
  if err != nil {
    fmt.Println("Error creating pipe:", err)
    return
  }

  if err := cmd.Start(); err != nil {
    fmt.Println("Error starting command:", err)
    return
  }

  scanner := bufio.NewScanner(stdout)
  for scanner.Scan() {
    fmt.Println(scanner.Text())
  }

  if err := cmd.Wait(); err != nil {
    fmt.Println("Error waiting command:", err)
  }
}

Результат выполнения кода:

go"Hello, Go!"

Пример

Давайте прочитаем вывод команды ls построчно:

gopackage main

import (
  "bufio"
  "fmt"
  "os/exec"
)

func main() {
  cmd := exec.Command("ls", "-l")
  stdout, err := cmd.StdoutPipe()
  if err != nil {
    fmt.Println("Error creating pipe:", err)
    return
  }

  if err := cmd.Start(); err != nil {
    fmt.Println("Error starting command:", err)
    return
  }

  scanner := bufio.NewScanner(stdout)
  lineCount := 0
  for scanner.Scan() {
    lineCount++
    fmt.Printf("Line %d: %s\n", lineCount, scanner.Text())
  }

  if err := cmd.Wait(); err != nil {
    fmt.Println("Error waiting command:", err)
  }
}

Результат выполнения кода:

go"Line 1: total 8"
"Line 2: -rw-r--r-- 1 user group 1234 Jun 1 12:34 file.txt"

Пример

Давайте обработаем вывод команды без ожидания завершения:

gopackage main

import (
  "bufio"
  "fmt"
  "os/exec"
  "time"
)

func main() {
  cmd := exec.Command("ping", "-c", "5", "google.com")
  stdout, err := cmd.StdoutPipe()
  if err != nil {
    fmt.Println("Error creating pipe:", err)
    return
  }

  if err := cmd.Start(); err != nil {
    fmt.Println("Error starting command:", err)
    return
  }

  scanner := bufio.NewScanner(stdout)
  for scanner.Scan() {
    line := scanner.Text()
    fmt.Println("Received:", line)
    time.Sleep(100 * time.Millisecond)
  }

  if err := cmd.Wait(); err != nil {
    fmt.Println("Command finished with error:", err)
  }
}

Результат выполнения кода:

go"Received: PING google.com (142.250.185.14): 56 data bytes"
"Received: 64 bytes from 142.250.185.14: icmp_seq=0 ttl=115 time=10.2 ms"
"Received: 64 bytes from 142.250.185.14: icmp_seq=1 ttl=115 time=9.8 ms"

Смотрите также

  • метод exec.Cmd.StdinPipe,
    который создает канал для отправки данных в команду
  • метод exec.Cmd.StderrPipe,
    который создает канал для чтения стандартных ошибок
  • метод exec.Cmd.Output,
    который возвращает вывод команды в виде слайса байт
  • метод exec.Cmd.CombinedOutput,
    который возвращает объединенный вывод и ошибки