Golang Go语言中 os/exec Command 子进程如何关闭继承自父进程的文件描述符

发布于 1周前 作者 htzhanglong 来自 Go语言

Golang Go语言中 os/exec Command 子进程如何关闭继承自父进程的文件描述符

google 没找到, 看文档也没到找到 求助

10 回复

这个应该是操作系统相关的吧
我猜一下, 子进程关闭的只是自己的复制描述符。关不了父进程的?

更多关于Golang Go语言中 os/exec Command 子进程如何关闭继承自父进程的文件描述符的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是子进程关闭自己的,比如父进程里面打开了某个文件,这个文件也会在子进程中打开
想要的是在 exec.Command 中有 close fds 的选项(关闭继承自父进程打开的文件描述符)

FD_CLOEXEC 的 flag
https://github.com/golang/go/issues/6537
syscall.Syscall(syscall.SYS_FCNTL, fd, syscall.F_SETFD, flag)

一个进程打开的文件 端口可能比较多,每一个都需要设置这个 flag 是不是太麻烦了

那就就得自己直接用 syscall 实现 exec.Command 了。看看 github 有没有现成的。

哦,好吧多谢了,我觉得可以给 Go 提一个 issue,exec.Command 应当也能支持这个 feature

如果是通过 go 标准库打开的,本身就已经设了 O_CLOEXEC,是不会被子进程继承的

我看了下,好像不通操作系统的实现不一样,有文档么

没有,不同操作系统当然不一样。其实你为什么要关心这个?

在Golang中,当你使用os/exec包来运行一个子进程时,默认情况下,子进程会继承父进程的所有打开的文件描述符(FDs)。在某些情况下,你可能希望限制或关闭这些继承的文件描述符,以避免资源泄露或提高安全性。

要关闭继承自父进程的文件描述符,你可以采取以下几种方法:

  1. 设置CloseFds标志: 在Unix-like系统上,你可以通过设置Cmd.SysProcAttr.SetsidCmd.SysProcAttr.Setpgid,并手动关闭不需要的文件描述符来间接实现。虽然这不是直接关闭FDs的方法,但它可以改变进程组,使得子进程无法接收来自父进程的一些信号和FDs。

  2. 使用文件描述符重定向: 在创建exec.Cmd实例后,你可以通过修改Cmd.ExtraFiles来明确指定哪些文件描述符应该被传递给子进程。这允许你精确控制哪些FDs是开放的,哪些是被关闭的。

  3. 使用更低级的系统调用: 对于更精细的控制,你可能需要使用cgo或其他方法调用更底层的系统调用,如unix.Setsid()unix.Dup2(),来直接操作文件描述符。

需要注意的是,直接操作文件描述符和进程属性通常涉及到系统特定的行为,因此在进行此类操作时,应确保你的代码在不同操作系统上的兼容性。在生产环境中使用前,务必进行充分的测试。

回到顶部