Go 如何读取子进程中的'exec.Cmd`外部文件fd?

Go 如何读取子进程中的'exec.Cmd`外部文件fd?,go,Go,我读了上面的解释,它是这样写的 // ExtraFiles specifies additional open files to be inherited by the // new process. It does not include standard input, standard output, or // standard error. If non-nil, entry i becomes file descriptor 3+i. // // BUG: on OS X 10.6,

我读了上面的解释,它是这样写的

// ExtraFiles specifies additional open files to be inherited by the
// new process. It does not include standard input, standard output, or
// standard error. If non-nil, entry i becomes file descriptor 3+i.
//
// BUG: on OS X 10.6, child processes may sometimes inherit unwanted fds.
// http://golang.org/issue/2603
ExtraFiles []*os.File
我不太明白这件事?例如,我在下面有这样的代码

cmd := &exec.Cmd{
    Path: init,
    Args: initArgs,
}
cmd.Stdin = Stdin
cmd.Stdout = Stdout
cmd.Stderr = Stderr
cmd.Dir = Rootfs
cmd.ExtraFiles = []*os.File{childPipe}
这意味着,由于我已经在
cmd.ExtraFiles=[]*os.File{childpipe}
中编写了一个childpipe,因此我可以通过直接编写fd
3
来使用它

pipe = os.NewFile(uintptr(3), "pipe")
json.NewEncoder(pipe).Encode(newThing)

如果有人能提供帮助,谢谢

正确;通过创建一个新的
*文件
,可以从管道中读取数据,该文件的文件描述符为子管道的文件描述符。下面是从子流程到父流程的管道数据示例:

家长:

package main

import (
    "fmt"
    "os/exec"
    "os"
    "encoding/json"
)

func main() {
    init := "child"
    initArgs := []string{"hello world"}

    r, w, err := os.Pipe()
    if err != nil {
        panic(err)
    }

    cmd := exec.Command(init, initArgs...)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.ExtraFiles = []*os.File{w}

    if err := cmd.Start(); err != nil {
        panic(err)
    }
    var data interface{}
    decoder := json.NewDecoder(r)
    if err := decoder.Decode(&data); err != nil {
        panic(err)
    }
    fmt.Printf("Data received from child pipe: %v\n", data)
}
package main

import (
    "os"
    "encoding/json"
    "strings"
    "fmt"
)

func main() {
    if len(os.Args) < 2 {
        os.Exit(1)
    }
    arg := strings.ToUpper(os.Args[1])

    pipe := os.NewFile(uintptr(3), "pipe")
    err := json.NewEncoder(pipe).Encode(arg)
    if err != nil {
        panic(err)
    }
    fmt.Println("This message printed to standard output, not to the pipe")
}
子项:

package main

import (
    "fmt"
    "os/exec"
    "os"
    "encoding/json"
)

func main() {
    init := "child"
    initArgs := []string{"hello world"}

    r, w, err := os.Pipe()
    if err != nil {
        panic(err)
    }

    cmd := exec.Command(init, initArgs...)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.ExtraFiles = []*os.File{w}

    if err := cmd.Start(); err != nil {
        panic(err)
    }
    var data interface{}
    decoder := json.NewDecoder(r)
    if err := decoder.Decode(&data); err != nil {
        panic(err)
    }
    fmt.Printf("Data received from child pipe: %v\n", data)
}
package main

import (
    "os"
    "encoding/json"
    "strings"
    "fmt"
)

func main() {
    if len(os.Args) < 2 {
        os.Exit(1)
    }
    arg := strings.ToUpper(os.Args[1])

    pipe := os.NewFile(uintptr(3), "pipe")
    err := json.NewEncoder(pipe).Encode(arg)
    if err != nil {
        panic(err)
    }
    fmt.Println("This message printed to standard output, not to the pipe")
}
主程序包
进口(
“操作系统”
“编码/json”
“字符串”
“fmt”
)
func main(){
如果len(os.Args)<2{
操作系统退出(1)
}
arg:=strings.ToUpper(os.Args[1])
管道:=os.NewFile(uintpttr(3),“管道”)
err:=json.NewEncoder(管道).Encode(arg)
如果错误!=零{
恐慌(错误)
}
fmt.Println(“此消息打印到标准输出,而不是管道”)
}

正确;通过创建一个新的
*文件
,可以从管道中读取数据,该文件的文件描述符为子管道的文件描述符。下面是从子流程到父流程的管道数据示例:

家长:

package main

import (
    "fmt"
    "os/exec"
    "os"
    "encoding/json"
)

func main() {
    init := "child"
    initArgs := []string{"hello world"}

    r, w, err := os.Pipe()
    if err != nil {
        panic(err)
    }

    cmd := exec.Command(init, initArgs...)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.ExtraFiles = []*os.File{w}

    if err := cmd.Start(); err != nil {
        panic(err)
    }
    var data interface{}
    decoder := json.NewDecoder(r)
    if err := decoder.Decode(&data); err != nil {
        panic(err)
    }
    fmt.Printf("Data received from child pipe: %v\n", data)
}
package main

import (
    "os"
    "encoding/json"
    "strings"
    "fmt"
)

func main() {
    if len(os.Args) < 2 {
        os.Exit(1)
    }
    arg := strings.ToUpper(os.Args[1])

    pipe := os.NewFile(uintptr(3), "pipe")
    err := json.NewEncoder(pipe).Encode(arg)
    if err != nil {
        panic(err)
    }
    fmt.Println("This message printed to standard output, not to the pipe")
}
子项:

package main

import (
    "fmt"
    "os/exec"
    "os"
    "encoding/json"
)

func main() {
    init := "child"
    initArgs := []string{"hello world"}

    r, w, err := os.Pipe()
    if err != nil {
        panic(err)
    }

    cmd := exec.Command(init, initArgs...)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.ExtraFiles = []*os.File{w}

    if err := cmd.Start(); err != nil {
        panic(err)
    }
    var data interface{}
    decoder := json.NewDecoder(r)
    if err := decoder.Decode(&data); err != nil {
        panic(err)
    }
    fmt.Printf("Data received from child pipe: %v\n", data)
}
package main

import (
    "os"
    "encoding/json"
    "strings"
    "fmt"
)

func main() {
    if len(os.Args) < 2 {
        os.Exit(1)
    }
    arg := strings.ToUpper(os.Args[1])

    pipe := os.NewFile(uintptr(3), "pipe")
    err := json.NewEncoder(pipe).Encode(arg)
    if err != nil {
        panic(err)
    }
    fmt.Println("This message printed to standard output, not to the pipe")
}
主程序包
进口(
“操作系统”
“编码/json”
“字符串”
“fmt”
)
func main(){
如果len(os.Args)<2{
操作系统退出(1)
}
arg:=strings.ToUpper(os.Args[1])
管道:=os.NewFile(uintpttr(3),“管道”)
err:=json.NewEncoder(管道).Encode(arg)
如果错误!=零{
恐慌(错误)
}
fmt.Println(“此消息打印到标准输出,而不是管道”)
}