exec.Cmd.Run în Go

Pornește comanda și așteaptă să se termine; returnează eroare dacă nu a pornit sau a ieșit cu cod diferit de 0.

Sintaxă
func (c *Cmd) Run() error

Ce face exec.Cmd.Run

Run = Start + Wait. Programul tău stă și așteaptă până când comanda se termină. Ieșirea comenzii merge unde ai setat Stdout/Stderr (implicit este aruncată).

Eroarea returnată poate fi: o eroare de pornire (programul nu există, nu ai drepturi) sau un *exec.ExitError, dacă programul a rulat dar a ieșit cu un cod diferit de 0. Din ExitError afli codul cu ExitCode().

Ce returnează

nil dacă programul a ieșit cu codul 0, altfel o eroare.

Exemple

Exemplul 1: Succes și cod de ieșire diferit de 0

package main

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

func main() {
    fmt.Println("true:", exec.Command("true").Run())

    err := exec.Command("sh", "-c", "exit 3").Run()
    fmt.Println("exit 3:", err)

    var ee *exec.ExitError
    if errors.As(err, &ee) {
        fmt.Println("codul de ieșire:", ee.ExitCode())
    }
}

Rezultat

true: <nil>
exit 3: exit status 3
codul de ieșire: 3

Exemplul 2: Verificarea existenței unui fișier cu test

package main

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

func main() {
    os.WriteFile("backup.tar", nil, 0o644)
    for _, f := range []string{"backup.tar", "lipsa.tar"} {
        err := exec.Command("test", "-f", f).Run()
        fmt.Printf("%s există: %v\n", f, err == nil)
    }
}

Rezultat

backup.tar există: true
lipsa.tar există: false

Exemplul 3: Ieșirea și erorile pe ecran

Erorile programului (stderr) le trimitem tot pe ieșirea standard, ca să apară în rezultat. Textul exact al mesajului lui ls diferă între macOS (aici) și Linux.

package main

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

func main() {
    cmd := exec.Command("ls", "exista.txt", "lipsa.txt")
    os.WriteFile("exista.txt", nil, 0o644)
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stdout
    err := cmd.Run()
    fmt.Println("eroare:", err)
}

Rezultat

ls: lipsa.txt: No such file or directory
exista.txt
eroare: exit status 1

Greșeli frecvente

  • Apelezi Run și te miri că nu vezi nimic. Fără Stdout setat, ieșirea comenzii este aruncată; folosește Output sau setează cmd.Stdout.
  • Rulezi o comandă care poate dura la nesfârșit fără limită de timp. Folosește exec.CommandContext cu un context cu timeout.

Comenzi înrudite

  • exec.Cmd.Output: Rulează comanda, așteaptă să se termine și returnează ce a scris pe ieșirea standard (stdout).
  • exec.Cmd.CombinedOutput: Rulează comanda și returnează împreună ieșirea standard și mesajele de eroare (stdout + stderr).
  • exec.Cmd.Start: Start pornește comanda fără să aștepte; Wait așteaptă terminarea ei și eliberează resursele.
  • exec.CommandContext: Ca exec.Command, dar procesul este oprit automat când contextul expiră sau este anulat.