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

huangapple go评论88阅读模式
英文:

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)

// 编译没有问题,但是类型转换失败了,不知道为什么
eerr, _ := err.(*syscall.Errno); os.Exit(int(*eerr))

// 引发 panic
reflect.ValueOf(err).Int()

看起来你可以将syscall.Errno与其他整数进行比较,但是实际上尝试获取其值让我感到困惑...

英文:

Let's say I try to acquire a lock, fail, and want to exit the program.

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

The problem is you need to pass an integer to os.Exit.

I've tried:

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()

It seems like you can compare the syscall.Errno to other integers, but actually trying to get the value of it is escaping me...

答案1

得分: 3

你通常可以将 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 被用作值,而不是指针,所以不需要尝试使用 * 解引用它。

英文:

You can normally just convert a syscall.Errno to an int

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

syscall.Errno is defined as a uintptr, which can be converted directly to an int. There's no interface, assertion, or reflection involved.

But when receiving it as an error interface, you need to assert it first.

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

The syscall.Errno is used as a value, not a pointer, no need to try and dereference it with *.

答案2

得分: -1

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

退出值和errno值都可以是整数,但它们在其他方面没有共同之处。

特别是,EPERM通常(总是?)是“1”,但是shell通常处理/期望退出代码为1表示“替代成功”,而不是失败(例如,当grep找不到匹配项时)。

另一个例子是,BSD的sysexits(3) manpageexit定义了一些值。

然而,Go语言(更加与操作系统无关)不使用这些值。例如,flag包使用“2”而不是BSD建议的“64”(EX_USAGE)作为退出代码。(注意,在BSD中,64作为errno值是EHOSTDOWN)。

英文:

Don't use errno values as exit codes.

Exit values and errno values may both be integers, but they otherwise have nothing in common.

In particular, EPERM is often (always?) "1" but shells often handle/expect that an exit code of one is "alternate success" rather than failure (for example, when grep doesn't find a match).

An additional example,
the sysexits(3) manpage
for the BSDs define some values for use with exit.

However, Go (being more OS agnostic) doesn't use these.
E.g. the flag package exits with "2" instead of "64" (EX_USAGE) as recommended by BSD. (Note, on BSD 64 as an errno value is EHOSTDOWN).

huangapple
  • 本文由 发表于 2015年1月24日 05:45:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/28119214.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定