在Go中,是否可以写入控制台并回读?

时间:2015-06-24 21:55:42

标签: go stdout stdin console-input

我正在为Go编写一个CLI向导。我想做的是询问用户他想做什么,准备相应的CLI命令,并将其写入控制台。然后,用户可以通过按Enter键将命令提交给CLI,可能在首先编辑它之后。换句话说,我想将输出写入stdout,当用户按Enter键时,该输出将成为stdin的输入。有没有办法在Go中做到这一点?

2 个答案:

答案 0 :(得分:1)

直接从用户那里获取输入:

var s string
_, err := fmt.Scanf("%s", &s)

对于类似curses的应用程序,请看这里: https://github.com/rthornton128/goncurses/blob/master/ncurses.go

它有C绑定。

答案 1 :(得分:0)

我找到了一个Go命令行编辑器程序包https://github.com/peterh/liner,它包含了所请求的功能以及更多功能。它允许您编写具有历史记录和命令完成功能的CLI,命令完成功能提供了我在问题中所要求的内容:它提供了用户可以编辑并提交给CLI的文本。它支持Windows,Linux和Mac。以下是README中示例的略微修改版本,它运行一个带命令完成的简单CLI。例如,用户可以键入“j”并按Tab键循环显示名称列表,编辑一个名称,然后按Enter键提交。

package main

import (
    "fmt"
    "log"
    "os"
    "strings"

    "github.com/peterh/liner"
)

var (
    history_fn = ".liner_history"
    names      = []string{"jack", "john", "james", "mary", "mike", "nancy"}
)

func main() {
    line := liner.NewLiner()
    defer line.Close()

    line.SetCompleter(func(line string) (c []string) {
        for _, n := range names {
            if strings.HasPrefix(n, strings.ToLower(line)) {
                c = append(c, n)
            }
        }
        return
    })

    if f, err := os.Open(history_fn); err == nil {
        line.ReadHistory(f)
        f.Close()
    }

    line.SetCtrlCAborts(true)
    for true {
        if name, err := line.Prompt("What is your name? "); err != nil {
            if err.Error() == "EOF" || err == liner.ErrPromptAborted {
                break
            }
            log.Print("Error reading line: ", err)
        } else {
            log.Print("Got: ", name)
            line.AppendHistory(name)
        }
    }
    fmt.Printf("End of test\n")

    if f, err := os.Create(history_fn); err != nil {
        log.Print("Error writing history file: ", err)
    } else {
        line.WriteHistory(f)
        f.Close()
    }
}