Вопрос

I've got a command line tool written in Golang and I need to start vim from it. However it's not working, and there's not any error or much else to work with. I've reduced the code to just this:

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    cmd := exec.Command("vim", "test.txt")
    err := cmd.Run()
    fmt.Println(err)
}

When I run this, I can see the vim process for a 2-3 seconds but the application doesn't actually open. Then the program simply exits (and the vim process closes) with an "exit status 1".

I've also tried this to capture stderr:

package main

import (
    "bytes"
    "fmt"
    "os/exec"
)

func main() {
    cmd := exec.Command("vim", "test.txt")
    var stderr bytes.Buffer
    cmd.Stderr = &stderr
    err := cmd.Run()
    fmt.Println(err)
    fmt.Println(stderr)
}

But in this case, the program gets stuck indefinitely.

Any idea what could be the issue?

Это было полезно?

Решение

Pass on stdin and stdout from the calling program which, provided it was run from a terminal (likely for a command line program) will start vim for you and return control when the user has finished editing the file.

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main() {
    cmd := exec.Command("vim", "test.txt")
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    err := cmd.Run()
    fmt.Println(err)
}

Другие советы

VIM needs a proper terminal and detects the absence of one.

If you use the StderrPipe and read it while vim is running you will see this:

2014/02/02 20:25:49 Vim: Warning: Output is not to a terminal
2014/02/02 20:25:49 Vim: Warning: Input is not from a terminal

Example for reading stderr while executing (on play):

func logger(pipe io.ReadCloser) {
    reader := bufio.NewReader(pipe)

    for {
        output, err := reader.ReadString('\n')

        if err != nil {
            log.Println(err)
            return
        }

        log.Print(string(output))
    }
}

pipe, err := cmd.StderrPipe()

go logger(pipe)
cmd.Run()

For vim to run you probably need to emulate a terminal.

Maybe goat (doc) can help you out:

tty := term.NewTTY(os.Stdin)

cmd := exec.Command("vim", "test.txt")
cmd.Stdin = t
cmd.Stdout = t

// ...
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top