在运行命令时,如何从Go的附加文件描述符中读取数据?

huangapple go评论82阅读模式
英文:

How to read from Go additional file descriptors when running a command

问题

假设我有一个程序,它在文件描述符3上输出内容,就像这样:

package main

import "os"

func main() {
    fd3 := os.NewFile(3, "fd3")
    fd3.Write([]byte("FOOBAR\n"))
    fd3.Close()
}

现在,我想从一个Go程序中获取发送到文件描述符3的输出:

package main

import (
    "bufio"
    "fmt"
    "os/exec"
    "os"
)

func main() {
    cmd := exec.Command("./client")
    cmd.Stderr = os.Stderr
    fd3 := os.NewFile(3, "fd3")
    defer fd3.Close()

    cmd.ExtraFiles = []*os.File{fd3}

    err := cmd.Start()
    if err != nil {
        panic(err)
    }

    go func() {
        for {
            reader := bufio.NewReader(fd3)
            line, err := reader.ReadString('\n')
            if err != nil {
                panic(err)
            }
            fmt.Print(line)
        }
    }()

    cmd.Wait()

    fmt.Println("--- END ---")
}

但是,这段代码不起作用,它输出以下错误:

panic: read fd3: bad file descriptor

我不明白我的代码有什么问题。有人愿意帮忙吗?

英文:

Let's say I have a program than outputs things on file descriptor 3; something like this:

package main

import "os"

func main() {
	fd3 := os.NewFile(3, "fd3")
	fd3.Write([]byte("FOOBAR\n"))
	fd3.Close()
}

Now, I want to get the output sent to file descriptor 3 from a Go program:

package main

import (
	"bufio"
	"fmt"
	"os/exec"
	"os"
)

func main() {
	cmd := exec.Command("./client")
	cmd.Stderr = os.Stderr
	fd3 := os.NewFile(3, "fd3")
	defer fd3.Close()

	cmd.ExtraFiles = []*os.File{fd3}

	err := cmd.Start()
	if err != nil {
		panic(err)
	}

	go func() {
		for {
			reader := bufio.NewReader(fd3)
			line, err := reader.ReadString('\n')
			if err != nil {
				panic(err)
			}
			fmt.Print(line)
		}
	}()


	cmd.Wait()

	fmt.Println("--- END ---")
}

But that does not work as it outputs the following error:

panic: read fd3: bad file descriptor

I don't understand what's wrong with my code. Anyone willing to help?

答案1

得分: 3

os.NewFile实际上并不打开文件描述符。它实际上是一个API,用于包装给定给你的文件描述符。

请查看godoc:http://golang.org/pkg/os/#Create
(点击名称Create,它当前指向this

我认为你想调用os.Create(name)并将文件描述符传递给子进程,或者可能需要使用os.Open / os.OpenFile来设置模式等。

英文:

os.NewFile doesn't actually open a file descriptor. It's really an API to wrap a fd that was given to you.

look at the godoc: http://golang.org/pkg/os/#Create
(click the name Create, which currently points to this)

I think you want to call os.Create(name) and pass the fd to the child process
or potentiall os.Open / os.OpenFile if you need to set mode and stuff

huangapple
  • 本文由 发表于 2014年5月10日 16:51:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/23579024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定