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 cuRun.Runașteaptă finalul, deci citirea vine prea târziu; foloseșteStart.
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).