Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang - Read Os.stdin input but don't echo it

Tags:

In a golang program I'm reading the Os.Stdin input from a bufio.Reader.

After enter is pressed, the program reads the input and it is then printed onto the console. Is it possible to not print the input onto the console? After reading it, I process the input and reprint it (and no longer need the original input).

I read the data like this:

inputReader := bufio.NewReader(os.Stdin)
for {
    outgoing, _ := inputReader.ReadString('\n')
    outs <- outgoing
}
like image 712
Nevermore Avatar asked Jun 29 '16 08:06

Nevermore


2 Answers

I cannot think to other methods than to use ANSI escape codes to clear the terminal and move the cursor to a specific location (in your case to column 1:row 1).

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

And here are some basic helper methods to ease your job working with terminal.

// 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")
}

Then inside your function you need to clear the terminal and move the cursor to the first column and first row of the terminal window. At the end you have to output the computed result.

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
}
like image 196
Endre Simo Avatar answered Oct 13 '22 01:10

Endre Simo


It seems you are looking for a terminal-specific function to disable echo. This is usually used when writing passwords on the terminal (you can type but you don't see the characters).

I suggest you give a try to terminal.ReadPassword it should work nicely and probably in the most cross-platform compatible way.

prompt := ""
t := terminal.NewTerminal(os.Stdin, prompt)
for {
    outgoing, err := t.ReadPassword(prompt)
    if err != nil {
        log.Fatalln(err)
    }
    outs <- outgoing
}
like image 37
toqueteos Avatar answered Oct 13 '22 00:10

toqueteos