exec.Cmd.Start în Go

Start pornește comanda fără să aștepte; Wait așteaptă terminarea ei și eliberează resursele.

Sintaxă
func (c *Cmd) Start() error
func (c *Cmd) Wait() error

Ce face exec.Cmd.Start

Start pornește procesul și se întoarce imediat, astfel încât programul tău poate face altceva în timp ce comanda rulează. După Start, cmd.Process.Pid conține PID-ul procesului copil.

Wait așteaptă terminarea comenzii, termină copierea datelor din Stdin/Stdout/Stderr și returnează aceeași eroare ca Run. Orice Start reușit trebuie urmat de un Wait, altfel resursele procesului nu sunt eliberate.

Ce returnează

Start: nil dacă procesul a pornit. Wait: nil sau eroarea de ieșire (*exec.ExitError).

Exemple

Exemplul 1: Mai multe comenzi în paralel

Pornim trei comenzi care durează câte 200 ms; în total așteptăm aproximativ 200 ms, nu 600.

package main

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

func main() {
    inceput := time.Now()
    var comenzi []*exec.Cmd
    for i := 1; i <= 3; i++ {
        cmd := exec.Command("sleep", "0.2")
        if err := cmd.Start(); err != nil {
            fmt.Println("eroare:", err)
            return
        }
        comenzi = append(comenzi, cmd)
    }
    for i, cmd := range comenzi {
        fmt.Println("comanda", i+1, "terminată:", cmd.Wait())
    }
    fmt.Println("sub 500 ms:", time.Since(inceput) < 500*time.Millisecond)
}

Rezultat

comanda 1 terminată: <nil>
comanda 2 terminată: <nil>
comanda 3 terminată: <nil>
sub 500 ms: true

Exemplul 2: Oprirea unei comenzi care durează prea mult

package main

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

func main() {
    cmd := exec.Command("sleep", "30")
    cmd.Start()
    fmt.Println("pornit, PID > 0:", cmd.Process.Pid > 0)

    time.Sleep(100 * time.Millisecond)
    cmd.Process.Kill()
    err := cmd.Wait()
    fmt.Println("Wait:", err)
}

Rezultat

pornit, PID > 0: true
Wait: signal: killed

Greșeli frecvente

  • Apelezi Start fără Wait. Procesul terminat rămâne „zombie” în sistem până se termină programul tău.
  • Citești din StdoutPipe după Wait. Wait închide pipe-ul; citește tot înainte.

Comenzi înrudite

  • exec.Cmd.Run: Pornește comanda și așteaptă să se termine; returnează eroare dacă nu a pornit sau a ieșit cu cod diferit de 0.
  • exec.Cmd.StdoutPipe: Returnează un Reader legat de ieșirea comenzii, ca să citești rezultatul pe măsură ce apare.
  • exec.CommandContext: Ca exec.Command, dar procesul este oprit automat când contextul expiră sau este anulat.
  • os.Getpid: Getpid returnează ID-ul procesului curent; Getppid, ID-ul procesului care l-a pornit (părintele).