无法使用os / exec包执行go文件

时间:2014-12-12 20:34:53

标签: go

我正在关注golang tutorial来编写我的网络应用。我正在修改tutorial page中的代码,以便我可以将保存的页面作为go代码执行(类似于go playground)。但是当我尝试使用os/exec包执行保存的go文件时,会抛出以下错误。

  

exec:" go run testcode.go":$ PATH中找不到可执行文件

以下是我修改后的代码:

// Structure to hold the Page
type Page struct {
    Title  string
    Body   []byte
    Output []byte
}

// saving the page
func (p *Page) save() { // difference between func (p *Page) and func (p Page)
    filename := p.Title + ".go"
    ioutil.WriteFile(filename, p.Body, 0777)
}

// handle for the editing
func editHandler(w http.ResponseWriter, r *http.Request) {
    title := r.URL.Path[len("/edit/"):]

    p, err := loadPage(title)

    if err != nil {
        p = &Page{Title: title}
    }
    htmlTemp, _ := template.ParseFiles("edit.html")
    htmlTemp.Execute(w, p)
}

// saving the page
func saveHandler(w http.ResponseWriter, r *http.Request) {
    title := r.URL.Path[len("/save/"):]
    body := r.FormValue("body")

    p := Page{Title: title, Body: []byte(body)}
    p.save()

    http.Redirect(w, r, "/exec/"+title, http.StatusFound) // what is statusfound
}

// this function will execute the code.
func executeCode(w http.ResponseWriter, r *http.Request) {

    title := r.URL.Path[len("/exec/"):]

    cmd := "go run " + title + ".go"
    //cmd = "go"
    fmt.Print(cmd)
    out, err := exec.Command(cmd).Output()

    if err != nil {
        fmt.Print("could not execute")
        fmt.Fprint(w, err)
    } else {
        p := Page{Title: title, Output: out}

        htmlTemp, _ := template.ParseFiles("output.html")
        htmlTemp.Execute(w, p)
    }
}

请告诉我为什么我无法执行go文件。

2 个答案:

答案 0 :(得分:14)

您正在以错误的方式调用命令。第一个字符串是可执行文件的完整路径

os.exec.Commandfunc Command(name string, arg ...string)

所以你想要exec.Command("/usr/bin/go", "run", title+".go")

答案 1 :(得分:1)

接受的答案表明os.exec.Command的第一个参数是可执行文件的完整路径。来自文档:

"如果name不包含路径分隔符, Command使用LookPath 可以解析完整名称的路径(如果可能)。否则它直接使用名称"。

除了在之前建议的可执行文件名之后传递参数之外,您应该采取哪些措施来避免executable file not found in $PATH错误,将您的PATH设置在SHELL中或使用os.Setenv。如果您对所指示的命令的完整位置进行硬编码,则您的程序可能无法移植到另一个Unix操作系统。

例如,命令lspci位于ubuntu中的/usr/bin下和RHEL中的/sbin/下。如果你这样做:

os.Setenv("PATH", "/usr/bin:/sbin")
exec.Command("lspci", "-mm")

然后你的程序将在ubuntu和RHEL中执行。

或者,形成shell,您也可以执行:PATH=/sbin; my_program

注意:上述命令将PATH限制为明确指示的路径。例如,如果要添加到shell中的现有路径,请执行PATH=/sbin:$PATH; my_program;在go中,您可以使用os.Getenv读取变量,然后在执行os.Setenv时附加到该变量。