【Golang】Exit Code

Posted by 西维蜀黍 on 2021-05-26, Last Modified on 2021-10-17

os.Exit()

Use os.Exit to immediately exit with a given status.

package main

import (
    "fmt"
    "os"
)

func main() {
    defer fmt.Println("!") // never called

    os.Exit(3)
}
  • Conventionally, code zero indicates success, non-zero an error
  • defers will not be run when using os.Exit, so this fmt.Println will never be called.
  • For portability, the status code should be in the range [0, 125].
// Exit causes the current program to exit with the given status code.
// Conventionally, code zero indicates success, non-zero an error.
// The program terminates immediately; deferred functions are not run.
//
// For portability, the status code should be in the range [0, 125].
func Exit(code int) {
	if code == 0 {
		// Give race detector a chance to fail the program.
		// Racy programs do not have the right to finish successfully.
		runtime_beforeExit()
	}
	syscall.Exit(code)
}

Obtain Exit Code

Note that unlike e.g. C, Go does not use an integer return value from main to indicate exit status. If you’d like to exit with a non-zero status you should use os.Exit.

If you run exit.go using go run, the exit will be picked up by go and printed.

By building and executing a binary you can see the status in the terminal.

$ go run exit.go
exit status 3

$ go build exit.go
$ ./exit
$ echo $?
3

Difference between Panic and os.Exit

Experiment

package main

import (
	"fmt"
)

func main() {
	defer fmt.Println("defer called")
	panic("test")
}

Output:

defer called
panic: test

goroutine 1 [running]:
main.main()
        /Users/shiwei/SW/GoPlayground/sw.go:9 +0x95

Process finished with exit code 2

Summary

  1. os.Exit skips the execution of deferred function.
  2. With os.Exit, you can specify the exit code.
  3. The exit code of panic is always 2
  4. panic somewhere can be caught and ignored or logged using recover, while no way to recover if os.Exit is called, which makes sense, as when you call os.Exit you wanna our program exits immediately.

If you need to execute the deferred function, you have no choice but panic. (On the other hand, if you want to skip execution of deferred function, use os.Exit.)

Under other conditions:

  1. Use panic when something really wired happens, e.g. programming logic error.
  2. Use os.Exit when you want an immediate exit, with specified exit code.

Reference