Golang - 读取Os.stdin输入但不回显它

时间:2016-06-29 08:46:18

标签: input go stdin

在golang程序中,我正在从bufio.Reader读取Os.Stdin输入。

按下enter后,程序读取输入,然后将其打印到控制台上。是否可以不将输入打印到控制台上?阅读后,我处理输入并重新打印(不再需要原始输入)。

我读了这样的数据:

inputReader := bufio.NewReader(os.Stdin)
for {
    outgoing, _ := inputReader.ReadString('\n')
    outs <- outgoing
}

3 个答案:

答案 0 :(得分:2)

除了使用ANSI escape codes清除终端并将光标移动到特定位置(在第1列:第1行中),我想不到其他方法。

var screen *bytes.Buffer = new(bytes.Buffer)
var output *bufio.Writer = bufio.NewWriter(os.Stdout)

以下是一些基本的辅助方法,可以帮助您轻松完成终端工作。

// Move cursor to given position
func moveCursor(x int, y int) {
    fmt.Fprintf(screen, "\033[%d;%dH", x, y)
}

// Clear the terminal
func clearTerminal() {
    output.WriteString("\033[2J")
}

然后在您的函数内部,您需要清除终端并将光标移动到终端窗口的第一列和第一行。最后,您必须输出计算结果。

for {
    outgoing, err := input.ReadString('\n')

    if err != nil {
        break
    }

    if _, err := fmt.Sscanf(outgoing, "%f", input); err != nil {
        fmt.Println("Input error!")
        continue
    }

    // Clear console
    clearTerminal()
    moveCursor(1,1)

    fmt.Println(outs) // prints the computed result
}

答案 1 :(得分:1)

您似乎正在寻找终端特定功能来禁用回声。这通常在终端上写密码时使用(您可以输入,但不会看到字符)。

我建议您尝试terminal.ReadPassword它应该可以很好地工作,并且可能以最跨平台兼容的方式。

prompt := ""
t := terminal.NewTerminal(os.Stdin, prompt)
for {
    outgoing, err := t.ReadPassword(prompt)
    if err != nil {
        log.Fatalln(err)
    }
    outs <- outgoing
}

答案 2 :(得分:1)

除了crypto / ssh / terminal;

package main

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

func raw(start bool) error {
    r := "raw"
    if !start {
        r = "-raw"
    }

    rawMode := exec.Command("stty", r)
    rawMode.Stdin = os.Stdin
    err := rawMode.Run()
    if err != nil {
        return err
    }

    return rawMode.Wait()
}

// http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html
func main() {
    var rs []rune
    raw(true)
    for {
        inp := bufio.NewReader(os.Stdin)
        r, _, err := inp.ReadRune()
        if err != nil {
            raw(false)
            panic(err)
        }

        if r == '\x03' { // ctrl+c
            break
        } else if r == '\r' { // enter
            fmt.Print(string(rs), "\n\r")
            rs = []rune{}
            continue
        } else if r == '\u007f' { // backspace
            fmt.Printf("\033[1D\033[K")
            continue
        }

        rs = append(rs, r)
    }

    raw(false)
}