为什么我在这个Go程序中使用stderr和ioutil获得"bad file descriptor"。全部阅读



命令"psql"应该会抛出一个错误,我正在尝试读取stderr并将其打印到Go程序中。我用ioutil。ReadAll从stderr和stdout读取数据。

不幸的是,它根本没有从stderr读取。ioutil。ReadAll返回一个错误,这不是我预期的错误。

我得到的错误是

read |0: bad file descriptor

这是代码。

package main
import (
        "fmt"
        "os/exec"
        "io/ioutil"
)
func main() {
        cmd := exec.Command("psql")
        stdout, err := cmd.StdoutPipe()
        if err != nil {
                fmt.Printf("Error: %s", err)
        }
        stderr, err := cmd.StderrPipe()
        if err != nil {
                fmt.Printf("Error: %s", err)
        }
        err = cmd.Start()
        if err != nil {
                fmt.Printf("Start error %s",err)
        }
        d := cmd.Wait()
        if d != nil {
                fmt.Println(d)
        }
        stdo,g := ioutil.ReadAll(stdout)
        stde,f := ioutil.ReadAll(stderr)
        if g != nil {
                fmt.Println(g)
        }
        if f !=nil {
                fmt.Println(f)
        }
        fmt.Printf("Standard err is %s n", stde)
        fmt.Printf("Standard out is %s n",stdo)
}

我发现,通过实验,我得到了错误,因为我正在调用

   stdo,g := ioutil.ReadAll(stdout)
   stde,f := ioutil.ReadAll(stderr)

之后

 d := cmd.Wait()

因此,在cmd.Wait()返回后,stdout、stderr管道将关闭。

以下是cmd.StderrPipe() 的代码注释

// StderrPipe returns a pipe that will be connected to the command's
// standard error when the command starts.
// The pipe will be closed automatically after Wait sees the command exit.

很明显,在stdout和stderr关闭后,我们无法读取它们。

在命令启动之前,我们也无法读取它们。所以我们必须把它们放在开始和等待之间。

以下是修复该问题的代码。

package main
import (
        "fmt"
        "os/exec"
        "io/ioutil"
)
func main() {
        cmd := exec.Command("psql")
        stdout, err := cmd.StdoutPipe()
        if err != nil {
                fmt.Printf("Error: %s", err)
        }
        stderr, err := cmd.StderrPipe()
        if err != nil {
                fmt.Printf("Error: %s", err)
        }
        err = cmd.Start()
        if err != nil {
                fmt.Printf("Start error %s",err)
        }
        stdo,g := ioutil.ReadAll(stdout)
        stde,f := ioutil.ReadAll(stderr)
        d := cmd.Wait()
        if d != nil {
                fmt.Println(d)
        }
        if g != nil {
                fmt.Println(g)
        }
        if f !=nil {
                fmt.Println(f)
        }
        fmt.Printf("Standard err is %s n", stde)
        fmt.Printf("Standard out is %s n",stdo)
}

相关内容

  • 没有找到相关文章

最新更新