尝试从Go程序中启动外部编辑器

I am trying to figure out how to launch an external editor from within a Go program, wait for the user to close the editor, and then continue execution of the program. Based on this SO answer, I currently have this code:

package main

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

func main() {
    fpath := os.TempDir() + "/thetemporaryfile.txt"
    f, err := os.Create(fpath)
    if err != nil {
        log.Printf("1")
        log.Fatal(err)
    }
    f.Close()

    cmd := exec.Command("vim", fpath)
    err = cmd.Start()
    if err != nil {
        log.Printf("2")
        log.Fatal(err)
    }
    err = cmd.Wait()
    if err != nil {
        log.Printf("Error while editing. Error: %v
", err)
    } else {
        log.Printf("Successfully edited.")
    }

}

When I run the program, I get this:

chris@DPC3:~/code/go/src/launcheditor$ go run launcheditor.go 
2012/08/23 10:50:37 Error while editing. Error: exit status 1
chris@DPC3:~/code/go/src/launcheditor$ 

I have also tried using exec.Run() instead of exec.Start(), but that doesn't seem to work either (though it doesn't fail at the same place).

I can get it to work if I use Gvim instead of Vim, but it refuses to work with both Vim and nano. I think it's related to Vim and nano running inside the terminal emulator instead of creating an external window.

Apparently, you have to set Stdin, Stdout and Stderr on the Cmd object to os.Std(in|out|err). Like this (assuming that the object is called cmd):

cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

Credit for solving this goes to the guys on #go-nuts on freenode.

Here in cmd := exec.Command("vim", fpath), you're doing more or less:

$ PATH= vim foo.txt
bash: vim: No such file or directory
$

Shell uses the PATH environment variable, exec.Command does not. You have to lookup the vim binary and pass its full path to exec.Command. exec.LookPath does that for you.

This works for me but it has the disadvantage of opening another terminal (which will automatically close after edition) :

cmd := exec.Command("/usr/bin/xterm", "-e", "vim "+fpath)