exec.Cmd.StdoutPipe în Go

Returnează un Reader legat de ieșirea comenzii, ca să citești rezultatul pe măsură ce apare.

Sintaxă
func (c *Cmd) StdoutPipe() (io.ReadCloser, error)

Ce face exec.Cmd.StdoutPipe

StdoutPipe creează un pipe: comanda scrie la un capăt, tu citești la celălalt prin io.ReadCloser-ul primit. Spre deosebire de Output, poți prelucra ieșirea rând cu rând, în timp ce comanda încă rulează, fără să aștepți finalul sau să ții totul în memorie.

Ordinea corectă: StdoutPipe → Start → citești tot (până la EOF) → Wait. Wait închide pipe-ul, deci nu-l apela înainte de a termina citirea. Există și StderrPipe și StdinPipe.

Ce returnează

Capătul de citire și nil, sau o eroare (de exemplu Stdout e deja setat).

Exemple

Exemplul 1: Citire rând cu rând dintr-o comandă

package main

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

func main() {
    cmd := exec.Command("sh", "-c", "for oras in Iași Cluj Sibiu; do echo $oras; sleep 0.05; done")
    out, err := cmd.StdoutPipe()
    if err != nil {
        fmt.Println("eroare:", err)
        return
    }
    if err := cmd.Start(); err != nil {
        fmt.Println("eroare:", err)
        return
    }
    s := bufio.NewScanner(out)
    for s.Scan() {
        fmt.Println("primit:", s.Text())
    }
    fmt.Println("Wait:", cmd.Wait())
}

Rezultat

primit: Iași
primit: Cluj
primit: Sibiu
Wait: <nil>

Exemplul 2: Decodare JSON direct din ieșire

package main

import (
    "encoding/json"
    "fmt"
    "os/exec"
)

func main() {
    cmd := exec.Command("echo", `{"oras":"Brașov","temperatura":18}`)
    out, _ := cmd.StdoutPipe()
    cmd.Start()

    var meteo struct {
        Oras        string
        Temperatura int
    }
    err := json.NewDecoder(out).Decode(&meteo)
    cmd.Wait()
    fmt.Printf("%+v %v\n", meteo, err)
}

Rezultat

{Oras:Brașov Temperatura:18} <nil>

Greșeli frecvente

  • Apelezi Wait înainte să citești tot. Pipe-ul se închide și pierzi date (sau primești „file already closed”).
  • Folosești StdoutPipe și cu Run. Run așteaptă finalul, deci citirea vine prea târziu; folosește Start.

Comenzi înrudite

  • exec.Cmd.Start: Start pornește comanda fără să aștepte; Wait așteaptă terminarea ei și eliberează resursele.
  • exec.Cmd.Output: Rulează comanda, așteaptă să se termine și returnează ce a scris pe ieșirea standard (stdout).
  • os.Pipe: Creează un pipe al sistemului de operare: ce scrii la un capăt (w) poți citi la celălalt (r).
  • bufio.NewScanner: Creează un bufio.Scanner, cel mai simplu mod de a citi un text rând cu rând (sau cuvânt cu cuvânt).