golang, cmd会泄露文件句柄

在go中用cmd生成新的process时, 在某些os中(包括linux的某些版本), 父进程的文件句柄会泄露到子进程中, 参看代码

    package main
    
    import (
        "fmt"
        "os"
        "os/exec"
    )
    
    func main() {
        a, _ := os.OpenFile("1", os.O_CREATE|os.O_RDWR, 0755)
        defer a.Close()
        cmd := exec.Command("sh", "-c", "lsof +D .; sleep 3")
        output, _ := cmd.CombinedOutput()
        fmt.Printf("%v\n", string(output))
    }

得到输出

    [root@GroupH-HA-1 tmp]# uname -a
    Linux GroupH-HA-1 2.6.18-194.el5xen #1 SMP Tue Mar 16 22:01:26 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
    [root@GroupH-HA-1 tmp]# ./main
    COMMAND  PID USER   FD   TYPE DEVICE    SIZE    NODE NAME
    bash    4693 root  cwd    DIR  253,0   32768 3506177 .
    main    6184 root  cwd    DIR  253,0   32768 3506177 .
    main    6184 root  txt    REG  253,0 2250464 3506237 ./main
    main    6184 root    3u   REG  253,0       0 3506238 ./1
    sh      6189 root  cwd    DIR  253,0   32768 3506177 .
    sh      6189 root    3u   REG  253,0       0 3506238 ./1
    lsof    6190 root  cwd    DIR  253,0   32768 3506177 .
    lsof    6191 root  cwd    DIR  253,0   32768 3506177 .

可以看到./1的文件句柄泄漏到了sh -c中, 目前为止没有特别好的解决方案

参看此处bug描述

comments powered by Disqus