2013-11-21 7 views
7

कमांड "psql" को एक त्रुटि फेंकनी चाहिए, और मैं stderr को पढ़ने और इसे गो प्रोग्राम में प्रिंट करने की कोशिश कर रहा हूं। मैं stoutr, और stdout से डेटा पढ़ने के लिए ioutil.ReadAll का उपयोग करें।मुझे stderr और ioutil का उपयोग करके इस गो प्रोग्राम में "खराब फ़ाइल डिस्क्रिप्टर" क्यों मिलता है। रीडअल

दुर्भाग्यवश यह 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) 
} 

उत्तर

10

मैंने पाया कि प्रयोग के माध्यम से है कि मैं त्रुटि हो रही है, तथ्य यह है कि मैं बोल रहा हूँ

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

के बाद

d := cmd.Wait() 

तो stdout, stderr क्या होता है की वजह से पाइप cmd.Wait() रिटर्न के बाद बंद हो जाता है।

यहाँ 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) 
} 
+0

ध्यान दें कि तुरंत त्रुटियों से निपटने के लिए यह एक अच्छा विचार है। आपके उदाहरण में, यदि 'ioutil.ReadAll (stdout) 'विफल रहता है, तो त्रुटि को संभालने से पहले ioutil.ReadAll (stderr)' और 'cmd.Wait()' कहा जाएगा। –

+0

हाँ, यह सच है। – ppone

संबंधित मुद्दे