Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not able to execute go file using os/exec package

Tags:

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.

like image 395
subhash kumar singh Avatar asked Dec 03 '22 18:12

subhash kumar singh


2 Answers

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")

like image 177
fabrizioM Avatar answered Jan 14 '23 20:01

fabrizioM


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.

like image 36
DavidGamba Avatar answered Jan 14 '23 22:01

DavidGamba