英文:
Not able to execute go file using os/exec package
问题
我正在遵循golang教程编写我的Web应用程序。我正在修改来自教程页面的代码,以便我可以将保存的页面作为go代码执行(类似于go playground)。但是,当我尝试使用os/exec
包执行保存的go文件时,它会抛出以下错误。
> exec: "go run testcode.go": 在$PATH中找不到可执行文件
以下是我修改后的代码:
// 保存页面的结构体
type Page struct {
Title string
Body []byte
Output []byte
}
// 保存页面
func (p *Page) save() { // func (p *Page)和func (p Page)之间的区别
filename := p.Title + ".go"
ioutil.WriteFile(filename, p.Body, 0777)
}
// 编辑处理函数
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)
}
// 保存处理函数
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) // StatusFound是什么意思
}
// 执行代码的函数
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("无法执行")
fmt.Fprint(w, err)
} else {
p := Page{Title: title, Output: out}
htmlTemp, _ := template.ParseFiles("output.html")
htmlTemp.Execute(w, p)
}
}
请告诉我为什么我无法执行go文件。
英文:
I am following the golang tutorial for writing my web app. I am modifying the code from tutorial page, so that I can execute the saved page as go code (similar to go playground). But when I try to execute the saved go file using the os/exec
package, it throws the following error.
> exec: "go run testcode.go": executable file not found in $PATH
Following is my modified code :
// 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)
}
}
Please tell me why I am not able to able to execute the go file.
答案1
得分: 16
你正在错误地调用命令。第一个字符串应该是可执行文件的完整路径。
os.exec.Command:func Command(name string, arg ...string)
所以你应该使用 exec.Command("/usr/bin/go", "run", title+".go")
。
英文:
You are invoking command in the wrong way. The first string is the full path to the executable
os.exec.Command:func Command(name string, arg ...string)
so you want exec.Command("/usr/bin/go", "run", title+".go")
答案2
得分: 1
接受的答案指出,os.exec.Command的第一个参数是可执行文件的完整路径。根据文档:
“如果name不包含路径分隔符,Command会使用LookPath来解析路径以获取完整的name。否则,它直接使用name”。
为了避免“在$PATH中找不到可执行文件”的错误,除了按照之前建议的在可执行文件名后传递参数之外,你还应该在SHELL中设置你的PATH
,或者使用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
时追加到该变量中。
英文:
The accepted answer states that the first argument to os.exec.Command is the full path to the executable. From the docs:
"If name contains no path separators, Command uses LookPath to resolve the path to a complete name if possible. Otherwise it uses name directly".
What you should do to avoid executable file not found in $PATH
errors, besides passing the arguments after the executable name as suggested before, is to set your PATH
either in your SHELL or using os.Setenv. If you hardcode the full location of the command like indicated, your program might not be portable to another Unix OS.
For example, the command lspci
is located under /usr/bin
in ubuntu and under /sbin/
in RHEL. If you do this:
os.Setenv("PATH", "/usr/bin:/sbin")
exec.Command("lspci", "-mm")
Then your program will excecute in both ubuntu and RHEL.
Or, form the shell, you can also do: PATH=/sbin; my_program
NOTE: The commands above are limiting the PATH
to the explicitly indicated paths. If you want to add to the existing path in the shell for example, do PATH=/sbin:$PATH; my_program
; In go you can probably read the variable with os.Getenv
and then append to that when doing os.Setenv
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论