Ruby $Stdin.Gets Without Showing Chars on Screen

Ruby $stdin.gets without showing chars on screen

There is a gem for such user interaction: highline.

password = ask("Password:  ") { |q| q.echo = false }

Or even:

password = ask("Password:  ") { |q| q.echo = "*" }

Hide user input in Ruby

Assuming you are using at least ruby 1.9, you can use the noecho method on IO: http://www.ruby-doc.org/stdlib-2.0/libdoc/io/console/rdoc/IO.html#method-i-noecho

So:

require 'io/console'
print "Password: "
STDIN.noecho(&:gets).chomp

This will not obfuscate the characters, but will simply leave the input terminal blank.

Ruby STDIN.getc does not read char on reception

There was an answer from Matz :)

UPDATE

Also, you can use gem entitled highline, because using above example may be linked with strange screen effects:

require "highline/system_extensions"
include HighLine::SystemExtensions

while k = get_character
print k.chr
end

How to hide password input from terminal in ruby script

Best method from @eclectic923's answer:

require 'io/console'
password = STDIN.noecho(&:gets).chomp

For 1.9.3 (and above), this requires you adding require 'io/console' to your code.

Original Answer:

Ruby "Password" is another alternative.

Get single char from console immediately

Yes, there are numerous ways to do this, and besides gems you can directly manipulate with terminfo through gems for termios, ncurses or stty program.

tty_param = `stty -g`
system 'stty raw'

a = IO.read '/dev/stdin', 1

system "stty #{tty_param}"

print a

remove and replace the text when putting a string into the console $stdin ruby

If you are trying to implement a chat app in terminal, the "appropriate" tool is curses. A curses library essentially lets you write a GUI in the terminal. It lets you define separate regions of the screen that you can update separately and also lets you read input without echoing it to the terminal.

Get an input in Ruby

puts automatically appends a newline (\n) after outputting the string to the screen. This is useful in most cases, but not always.

Use print if you don't want a newline:

print "Foo"

In this case, you probably also want to clear the existing line; you can do that with \r (for "carriage return"):

print "Foo\r"

This will move the cursor back to column 0. Be aware that it will not clear any characters − it merely moves the cursor back to column 0 so it can override characters. So for example this:

print "Hello\r"
print "Foo\r"

Will result in:

Foolo

Since Foo only outputs three characters − two less than those on the screen. To fix that, we need to add spaces:

print "Foo  \r"

There's also \b (backspace) to move the cursor one character back:

print "Foo"
print "\b\bee"

will result in:

Fee

All of this is rather tedious to work with, and exactly the reason why the curses library exists ;-) It wraps all of this in wrapper functions which deal with erasing the correct stuff and it was originally developed for ASCII games like this ;-) I recommend you use it!

Testing STDIN in Ruby

You can simply stub STDIN:

it "takes user's name and returns it" do
output = capture_standard_output { game.ask_for_name }
expect(output).to eq "What shall I call you today?"
allow(STDIN).to receive(:gets) { 'joe' }
expect(game.ask_for_name).to eq 'Joe'
end

Actually, you can do the same with STDOUT, without needing to change $stdout:

it "takes user's name and returns it" do
expect(STDOUT).to receive(:puts).with("What shall I call you today?")
allow(STDIN).to receive(:gets) { 'joe' }
expect(game.ask_for_name).to eq 'Joe'
end


Related Topics



Leave a reply



Submit