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

huangapple go评论92阅读模式
英文:

Trying to launch an external editor from within a Go program

问题

我正在尝试弄清楚如何从Go程序中启动外部编辑器,等待用户关闭编辑器,然后继续执行程序。根据这个SO答案,我目前有以下代码:

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\n", 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在终端模拟器中运行而不是创建外部窗口有关。

英文:

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\n", 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.

答案1

得分: 15

显然,你需要将Cmd对象上的StdinStdoutStderr设置为os.Std(in|out|err)。像这样(假设对象被称为cmd):

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

解决这个问题的功劳归功于freenode上的#go-nuts频道的人们。

英文:

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.

答案2

得分: 3

这对我来说是有效的,但它的缺点是会打开另一个终端(在编辑后会自动关闭):

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

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)

答案3

得分: 0

cmd := exec.Command("vim", fpath)中,你正在做更多或更少的事情:

$ PATH= vim foo.txt
bash: vim: 没有那个文件或目录
$

Shell使用PATH环境变量,而exec.Command不使用。你必须查找vim二进制文件并将其完整路径传递给exec.Commandexec.LookPath可以为你完成这个任务。

英文:

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.

huangapple
  • 本文由 发表于 2012年8月23日 16:57:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/12088138.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定