英文:
How can I read from `exec.Cmd` ExtraFiles fd in child process?
问题
我从golang.org上阅读了解释,它的说明如下:
// ExtraFiles指定要由新进程继承的其他打开文件。它不包括标准输入、标准输出或标准错误。如果非nil,则第i个条目变为文件描述符3+i。
BUG:在OS X 10.6上,子进程有时可能会继承不需要的文件描述符。http://golang.org/issue/2603
我对此不太理解。例如,我有以下代码:
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)
如果有人能提供帮助,谢谢!
英文:
I read the explanation from golang.org, it says like below.
// 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
I'm not very understand about it ? For example I have such code below.
cmd := &exec.Cmd{
Path: init,
Args: initArgs,
}
cmd.Stdin = Stdin
cmd.Stdout = Stdout
cmd.Stderr = Stderr
cmd.Dir = Rootfs
cmd.ExtraFiles = []*os.File{childPipe}
Is that mean, since I have written a childpipe in cmd.ExtraFiles = []*os.File{childPipe}
, I can use it by writing fd 3
directly.
pipe = os.NewFile(uintptr(3), "pipe")
json.NewEncoder(pipe).Encode(newThing)
Thanks if anyone can give some help!
答案1
得分: 6
正确;您可以通过创建一个新的*File
,其文件描述符是子进程管道的文件描述符,从管道中读取数据。以下是将数据从子进程传输到父进程的示例:
父进程:
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("从子进程管道接收到的数据:%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("此消息打印到标准输出,而不是管道")
}
英文:
Correct; you can read from the pipe by creating a new *File
whose file descriptor is that of the child pipe. Below is a example of piping data from the child process to the parent:
Parent:
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)
}
Child:
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")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论