2012-04-30 17 views
33

पर जाएं मैं ऑपरेटिंग सिस्टम में कमांड निष्पादित करने के लिए पैकेज का उपयोग कर रहा हूं: os/exec http://golang.org/pkg/os/exec/ लेकिन मुझे बाहर निकलने का तरीका प्राप्त करने का तरीका नहीं लगता है। मैं आउटपुट पढ़ सकता हूं हालांकिनिकास कोड प्राप्त करें -

यानी।

package main 

import(
    "os/exec" 
    "bytes" 
    "fmt" 
    "log" 
    ) 

func main() { 
    cmd := exec.Command("somecommand", "parameter") 
    var out bytes.Buffer 
    cmd.Stdout = &out 
    if err := cmd.Run() ; err != nil { 
     //log.Fatal(cmd.ProcessState.Success()) 
     log.Fatal(err) 
    } 
    fmt.Printf("%q\n", out.String()) 
} 

उत्तर

52

यह अगर बाहर निकलें कोड था और को 0 या कुछ और निर्धारित करने के लिए आसान है। पहले मामले में, cmd.Wait() शून्य वापस आ जाएगा (जब तक कि पाइप सेट करते समय कोई और त्रुटि न हो)।

दुर्भाग्यवश, त्रुटि मामले में निकास कोड प्राप्त करने के लिए कोई प्लेटफार्म स्वतंत्र तरीका नहीं है। यही कारण है कि यह एपीआई का हिस्सा नहीं है। निम्नलिखित स्निपेट लिनक्स के साथ काम करेंगे, लेकिन मैं अन्य प्लेटफार्मों पर यह परीक्षण नहीं किया:

package main 

import "os/exec" 
import "log" 
import "syscall" 

func main() { 
    cmd := exec.Command("git", "blub") 

    if err := cmd.Start(); err != nil { 
     log.Fatalf("cmd.Start: %v") 
    } 

    if err := cmd.Wait(); err != nil { 
     if exiterr, ok := err.(*exec.ExitError); ok { 
      // The program has exited with an exit code != 0 

      // This works on both Unix and Windows. Although package 
      // syscall is generally platform dependent, WaitStatus is 
      // defined for both Unix and Windows and in both cases has 
      // an ExitStatus() method with the same signature. 
      if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { 
       log.Printf("Exit Status: %d", status.ExitStatus()) 
      } 
     } else { 
      log.Fatalf("cmd.Wait: %v", err) 
     } 
    } 
} 

बस followtheapidocs अधिक :)

+1

मैंने दस्तावेज़ों में देखा लेकिन 'प्रोसेसस्टेट' से 'वेटस्टैटस' तक जाने का तरीका कभी नहीं मिला, आपने यह कैसे किया? इसके अलावा मुझे मेलिंग सूची में समाधान मिला है (जैसा कि आपने वर्णन किया है) https://groups.google.com/forum/?fromgroups#!searchin/golang-nuts/exit$20code/golang- पागल/dKbL1oOiCIY/Bz_haQYmMrcJ मैं इसे विंडोज़ में आजमा रहा हूं और आपको बताता हूं :) – OscarRyz

+0

यह निश्चित रूप से बाहर निकलने के लिए आसान नहीं है, लेकिन दस्तावेज़ कम से कम कुछ संकेत प्रदान करते हैं जहां आपको अगला देखना है। लेकिन वे विंडोज का बिल्कुल उल्लेख नहीं करते हैं, इसलिए मैं आपके उत्तर की प्रतीक्षा कर रहा हूं। – tux21b

+0

मेलिंग सूची विंडोज विशिष्ट के बारे में कुछ कहती है, लेकिन मैंने अभी यह कोड चलाया है और सही काम करता है, यह 1 पर है। – OscarRyz

8

यहाँ @ tux21b के आधार पर मेरे उन्नत संस्करण है पता लगाने के लिए ' रों जवाब

utils/cmd.go

package utils 

import (
    "bytes" 
    "log" 
    "os/exec" 
    "syscall" 
) 

const defaultFailedCode = 1 

func RunCommand(name string, args ...string) (stdout string, stderr string, exitCode int) { 
    log.Println("run command:", name, args) 
    var outbuf, errbuf bytes.Buffer 
    cmd := exec.Command(name, args...) 
    cmd.Stdout = &outbuf 
    cmd.Stderr = &errbuf 

    err := cmd.Run() 
    stdout = outbuf.String() 
    stderr = errbuf.String() 

    if err != nil { 
     // try to get the exit code 
     if exitError, ok := err.(*exec.ExitError); ok { 
      ws := exitError.Sys().(syscall.WaitStatus) 
      exitCode = ws.ExitStatus() 
     } else { 
      // This will happen (in OSX) if `name` is not available in $PATH, 
      // in this situation, exit code could not be get, and stderr will be 
      // empty string very likely, so we use the default fail code, and format err 
      // to string and set to stderr 
      log.Printf("Could not get exit code for failed program: %v, %v", name, args) 
      exitCode = defaultFailedCode 
      if stderr == "" { 
       stderr = err.Error() 
      } 
     } 
    } else { 
     // success, exitCode should be 0 if go is ok 
     ws := cmd.ProcessState.Sys().(syscall.WaitStatus) 
     exitCode = ws.ExitStatus() 
    } 
    log.Printf("command result, stdout: %v, stderr: %v, exitCode: %v", stdout, stderr, exitCode) 
    return 
} 

मैं इस पर परीक्षण किया है ओएसएक्स, अगर यह अन्य प्लेटफॉर्म पर अपेक्षित काम नहीं कर रहा है, तो कृपया मुझे बताएं ताकि हम इसे बेहतर बना सकें।

+0

उबंटू 16.04 लिनक्स पर काम करता है, और बाहर निकलने के साथ stdout देता है - बस जो मैं खोज रहा था ... – MrMobileMan

+0

इस समारोह को प्यार करें – n0nag0n

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