Ce face os.Exit
os.Exit termină procesul pe loc. Codul de ieșire spune sistemului (sau scriptului care a pornit programul) cum s-a terminat: 0 = succes, orice altă valoare (de obicei 1) = eroare. În shell îl vezi cu echo $?.
Foarte important: os.Exit NU rulează funcțiile amânate cu defer. Fișierele nu sunt închise de defer f.Close(), buffer-ele bufio.Writer nu sunt golite. Un model des folosit este o funcție run() error care face toată treaba (cu defer-uri), iar main apelează os.Exit(1) doar dacă ea returnează eroare.
Parametri
| Parametru | Descriere |
|---|---|
code |
Codul de ieșire: 0 pentru succes, 1–125 pentru erori. |
Ce returnează
Nu se întoarce niciodată.
Exemple
Exemplul 1: defer nu rulează
package main
import (
"fmt"
"os"
)
func main() {
defer fmt.Println("acest mesaj NU apare")
fmt.Println("închidem programul")
os.Exit(0)
}
Rezultat
închidem programul
Exemplul 2: Codul de ieșire văzut din shell
Programul verifică dacă a primit un nume de fișier și iese cu codul 2 dacă nu.
package main
import (
"fmt"
"os"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "utilizare: verifica <fisier>")
os.Exit(2)
}
fmt.Println("verific", os.Args[1])
}
Rezultat în terminal
$ go build -o verifica . && ./verifica; echo "cod: $?"
utilizare: verifica <fisier>
cod: 2
$ ./verifica note.txt; echo "cod: $?"
verific note.txt
cod: 0
Exemplul 3: Modelul run() + os.Exit
Programul se pornește pe el însuși ca proces copil (cu argumentul copil), ca să putem vedea codul de ieșire. În copil, defer-ul din run rulează, pentru că os.Exit vine abia după ce run s-a terminat.
package main
import (
"errors"
"fmt"
"os"
"os/exec"
)
func run() error {
defer fmt.Println("run: închid fișierele (defer)")
return errors.New("fișierul comenzi.csv lipsește")
}
func main() {
if len(os.Args) > 1 && os.Args[1] == "copil" {
if err := run(); err != nil {
fmt.Println("eroare:", err)
os.Exit(1)
}
return
}
exe, _ := os.Executable()
iesire, err := exec.Command(exe, "copil").CombinedOutput()
fmt.Print(string(iesire))
var ee *exec.ExitError
if errors.As(err, &ee) {
fmt.Println("codul de ieșire al copilului:", ee.ExitCode())
}
}
Rezultat
run: închid fișierele (defer)
eroare: fișierul comenzi.csv lipsește
codul de ieșire al copilului: 1
Greșeli frecvente
- Apelezi
os.Exitcând mai ai date într-unbufio.Writersau fișiere deschise cudefer Close(). Datele se pierd; golește-le înainte sau folosește modelul curun(). - Folosești
os.Exitîn bibliotecă (alt pachet decâtmain). O bibliotecă returnează erori; doarmaindecide când se oprește programul. - Ieși cu
os.Exit(0)după o eroare. Scripturile și sistemele de CI cred atunci că totul a mers bine.
Comenzi înrudite
log.Fatal: Scrie mesajul în jurnal și oprește imediat programul cu codul 1 (ca log.Print urmat de os.Exit(1)).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.os.Executable: Returnează calea fișierului executabil care rulează acum (programul compilat).