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

无法使用os/exec软件包执行go文件,go,Go,我正在遵循编写web应用程序的规则。我正在修改中的代码,以便以go代码的形式执行保存的页面(类似于)。但是,当我尝试使用os/exec包执行保存的go文件时,它抛出以下错误 exec:“go run testcode.go”:在$PATH中找不到可执行文件 以下是我修改过的代码: // Structure to hold the Page type Page struct { Title string Body []byte Output []byte } //

我正在遵循编写web应用程序的规则。我正在修改中的代码,以便以go代码的形式执行保存的页面(类似于)。但是,当我尝试使用
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文件。

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

func命令(名称字符串、参数…字符串)


因此,您需要执行命令(“/usr/bin/go”,“run”,title+“.go”)

接受的答案表明,要执行的第一个参数是可执行文件的完整路径。从文档中:

“如果名称不包含路径分隔符,命令使用LookPath将路径解析为完整的名称(如果可能)。否则,它直接使用名称。”

除了像前面建议的那样在可执行文件名后传递参数外,要避免在$PATH中找不到
可执行文件
错误,应该做的是在SHELL中或使用。如果按指示硬编码命令的完整位置,则程序可能无法移植到其他Unix操作系统

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

os.Setenv("PATH", "/usr/bin:/sbin")
exec.Command("lspci", "-mm")
那么你的程序在ubuntu和RHEL中都会非常出色

或者,在shell中,您也可以这样做:
PATH=/sbin;我的程序


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

时附加到该变量。是的,现在错误已更改为
fork/exec/usr/local/go/bin/go run ABSOLUTE\u PATH/testcode.go:无此类文件或目录
。Go文件被创建并在目录中可见,我也可以从终端运行程序(testcode.Go)。从终端使用那些精确的字符串?转到/root目录并尝试从那里执行您的文件yes使用
/usr/local/go/bin/go运行绝对路径/testcode.go
从终端执行。接受的答案是正确的。OP遇到的问题是,他们将整个多参数命令行作为可执行文件名插入第一个参数,以查找run,这正是accept答案指出并更正的内容。答案的唯一缺点是他们不需要使用完整路径(他们可能应该假设它在路径上;你真的不想像你建议的那样弄乱
path
环境变量)。如果你以root用户身份运行脚本,那么限制
path
以避免安全问题很重要。我编辑了我的答案,以确认您提出的问题。是的,但您的可执行文件不应破坏路径。OP执行的是
go
,你不知道它在哪里(是
/usr/local/bin/go
?,是
/opt/go/bin
?,是
$HOME/go1.5/bin
?),所以你应该给用户留一个合理的路径;只需尝试以
go
的形式执行命令,该命令将使用
LookPath
并在未找到时进行适当的投诉。限制路径不应该是一个随机程序的工作(除非它是一个特殊的setuid,但这是一个完全不同的蠕虫罐)。