英文:
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
对象上的Stdin
、Stdout
和Stderr
设置为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.Command
。exec.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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论