Попытка запустить внешний редактор из программы Go

Я пытаюсь выяснить, как запустить внешний редактор из программы Go, дождаться, пока пользователь закроет редактор, а затем продолжить выполнение программы. На основе этой Итак, ответьте, у меня в настоящее время есть этот код:

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: %vn", err)
    } else {
        log.Printf("Successfully edited.")
    }

}

когда я запускаю программу, я получаю это:

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$ 

Я также попытался с помощью exec.Run() вместо exec.Start(), но это, похоже, тоже не работает (хотя он не терпит неудачу в том же месте).

Я могу заставить его работать, если я использую Gvim вместо Vim, но он отказывается работать как с Vim, так и с nano. Я думаю, что это связано с Vim и nano, работающими внутри эмулятора терминала вместо создания внешнего окна.

3 ответов


по-видимому, вы должны установить Stdin, Stdout и Stderr на Cmd объект os.Std(in|out|err). Как это (предполагая, что объект называется cmd):

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

кредит для решения этой проблемы идет парням на #go-nuts на freenode.


это работает для меня, но у него есть недостаток открытия другого терминала (который автоматически закроется после выпуска):

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

здесь cmd := exec.Command("vim", fpath), вы делаете более или менее:

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

Shell использует переменную среды PATH,exec.Command нет. Вы должны искать vim binary и пройти полный путь к exec.Command. exec.LookPath делает это для вас.