Exit
La funzione Exit()
termina immediatamente il programma corrente, senza eseguire funzioni differite e ritorna il suo argomento alla shell come stato di ritorno.
(650exit.go):
package main
import "fmt"
import "os"
func main() {
// Le funzioni defer non vengono eseguite
// con Exit. La seguente non viene stampata
defer fmt.Println("!")
// Uscita con stato 3
os.Exit(0)
}
// Go non ha uno stato di ritorno per la funzione return
// La funzione Exit è l'unica con stato di ritorno
// per la shell
Un programma che ha eseguito normalmente, senza Panic()
o Exit()
ritorna la stato 0 alla shell, successo.
Ogni altro stato di ritorno indica fallimento.
Lo stato di ritorno è limitato al range 0-255.
La Realtà
Il codice di ritorno alla shell è inviato correttamente solo se il programma è stato compilato con go build
e lanciato da eseguibile, non se viene lanciato con go run
. Quest'ultimo genera un programma di inviluppo per il nostro programma finale.
Proviamo l'esempio:
(651-return-code.go):
package main
import "os"
func main() {
os.Exit(0)
}
Lanciamolo con:
go run 65a-return-code.go
Non da alcun output, naturalmente, nè nessun messaggio, e il suo stato di ritorno, testato col comando shell echo $?
è 0.
Ora proviamo il programma:
(652-return-code.go):
package main
import "os"
func main() {
os.Exit(100)
}
Lanciamolo con:
go run 65b-return-code.go
Produce il messaggio:
exit status 100
che è inviato a standard error.
Il suo stato di ritorno, testato con echo $?
è 1.
Ma se entrambi i programmi vengono compilati col comando go build
il comportamento è quello documentato nel manuale.
Il motivo è che go run programma
non lancia il programma direttamente ma fa partire un programma di gestione front end, che compila il programma in una directory temporanea e lo esegue.
Il programma vero passa lo stato di ritorno al gestore, che lo stampa come messaggio. Il programma vero non è figlio della shell, ma del gestore.
Il gestore, che è figlio della shell, passa un generico stato alla shell che è sempre 0 per successo e 1 per fallimento.