Hi there! I am trying to read data from stdin, and am havig some trouble when there is less than a line of data. Here’s some sample code:
m = IO::Memory.new
STDIN.read_buffering=false
m << STDIN.gets_to_end
pp! m.to_s
If I run it and type “1234<Ctrl+D>” this should print 1234, but doesn’t, it just keeps waiting for more input.
Unless I send Ctrl+D right after a newline, it always keeps waiting for data, so
1234\n<Ctrl+D> works
1234\n5678<Ctrl+D> doesn’t
Any ideas?
Update: This works, which is more confusing to me
echo -n "hola" | crystal run stdin.cr
m.to_s # => "hola"
UPDATE
found some code in stack overflow that solves the whole thing (even shows how to do “echo * for passwords” if desired
# Fix for crystal bug
STDIN.blocking = true
# STDIN chars without buffering
STDIN.raw do
# Dont echo out to the terminal
STDIN.noecho do
final_password = ""
while char = STDIN.read_char
# If we have a backspace
if char == '\u{7f}'
# Move the cursor back 1 char
if final_password != ""
STDOUT << "\b \b"
STDOUT.flush
final_password = final_password[0...-1]
end
next
elsif char == '\u{3}'
# Control + C was pressed. Get outta here
Process.exit 0
elsif char == '\u{4}'
# Control + D was pressed. Finished
break
elsif char.ascii_control?
# A Control + [] char was pressed. Not valid for a password
next
end
STDOUT << "*"
STDOUT.flush
final_password += char
end
puts final_password
end
end