gpt4 book ai didi

unix - 如何在 Go 中以跨平台的方式按名称列出可用的操作系统信号?

转载 作者:IT王子 更新时间:2023-10-29 02:22:14 26 4
gpt4 key购买 nike

假设我正在 Go 中实现 kill 程序。我可以从命令行接受数字信号和 PID,并将它们发送到 syscall.Kill 没问题。

但是,我不知道如何实现信号调度的“字符串”形式,例如kill -INT 12345

真正的用例是提示用户发送终止信号的较大程序的一部分;不能替代 kill

问题:

如何在任何受支持的平台上在运行时将有效信号名称转换为信号编号(或者至少无需编写要在编译时运行的每个平台代码)?

我尝试过的:

  • 保留信号名称到数字的静态映射。这不适用于跨平台方式(例如,kill -l 在 Mac OSX 上与现代 Linux 和旧版 Linux 上返回不同的信号列表)。使该解决方案在一般情况下正常工作的唯一方法是为每个操作系统制作 map ,这需要我了解每个操作系统的行为,并在它们添加新信号支持时保持最新状态。
  • 退出 GNU kill 工具并从中捕获信号列表。这是不优雅的,有点自相矛盾,还需要 a) 能够找到 kill,b) 具有执行子进程的能力/许可,以及 c) 能够预测/解析输出kill-the-binary.
  • 使用各种Signal 类型的String 方法。这只返回包含信号编号的字符串,例如os.Signal(4).String() == "signal 4",没有用。
  • 调用私有(private)函数runtime.signame ,这正是我想要的。 go://linkname hacks 会起作用,但我假设这种事情是有原因的。

我还没有尝试过的想法/事情:

  • 以某种方式使用 CGo。我宁愿不冒险进入 CGO 领域的项目,否则根本不是低级别/不需要本地集成。如果那是唯一的选择,我愿意,但不知道从哪里开始。
  • 使用模板和代码生成在编译时根据外部源构建信号列表。出于与 CGo 相同的原因,这不是可取的。
  • 以某种方式反射(reflect)和解析以SIG 开头的syscall 成员。有人告诉我这是不可能的,因为名称被编译掉了;是否有可能,对于像信号名称这样基本的东西,它们在某个地方没有被编译掉?

最佳答案

提交 d455e41于 2019 年 3 月将此功能添加为 sys/unix.SignalNum(),因此至少从 Go 1.13 开始可用。 GitHub 问题中的更多详细信息 #28027 .

来自documentation golang.org/x/sys/unix 包的:

func SignalNum(s string) syscall.Signal

SignalNum returns the syscall.Signal for signal named s, or 0 if a signal with such name is not found. The signal name should start with "SIG".

要回答类似的问题,“我如何列出所有可用信号的名称(在给定的类 Unix 平台上)”,我们可以使用反函数 sys/unix.SignalName():

    import "golang.org/x/sys/unix"

// See https://github.com/golang/go/issues/28027#issuecomment-427377759
// for why looping in range 0,255 is enough.
for i := syscall.Signal(0); i < syscall.Signal(255); i++ {
name := unix.SignalName(i)
// Signal numbers are not guaranteed to be contiguous.
if name != "" {
fmt.Println(name)
}
}

关于unix - 如何在 Go 中以跨平台的方式按名称列出可用的操作系统信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42598522/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com