你如何将 syscall.Errno 传递给 os.Exit?

How do you pass syscall.Errno to os.Exit?

假设我尝试获取锁,但失败了,想退出程序。

err = syscall.Flock(lockfd, syscall.LOCK_EX|syscall.LOCK_NB)
if err == syscall.EAGAIN {
    os.Exit(err)
}

问题是您需要将整数传递给 os.Exit。

我试过:

os.Exit(int(err))
os.Exit(syscall.EAGAIN)

// Compiles fine, but the cast fails.. no idea why
eerr, _ := err.(*syscall.Errno); os.Exit(int(*eerr)) 

// panics
reflect.ValueOf(err).Int()

看起来你可以将 syscall.Errno 与其他整数进行比较,但实际上试图获得它的值是在逃避我...

您通常可以将 syscall.Errno 转换为 int

if err == syscall.EAGAIN {
    os.Exit(int(err))
}

syscall.Errno定义为uintptr,可以直接转换为int。不涉及接口、断言或反射。

但是作为error接口接收时,需要先断言

if err == syscall.EAGAIN {
    os.Exit(int(err.(syscall.Errno)))
}

syscall.Errno 用作值,而不是指针,无需尝试使用 * 取消引用。

不要使用 errno 值作为退出代码。

退出值和 errno 值可能都是整数,但它们在其他方面没有任何共同点。

特别是,EPERM 通常(总是?)“1”,但 shell 通常 handle/expect 一个退出代码是 "alternate success" 而不是失败(例如,当grep 找不到匹配项。

再举一个例子, sysexits(3) manpage 为 BSD 定义一些用于 exit.

的值

然而,Go(更 OS 不可知)不使用这些。 例如。按照 BSD 的建议,标志包以“2”而不是“64”(EX_USAGE) 退出。 (注意,在 BSD 64 上,errno 值为 EHOSTDOWN)。