Hi,

2009/7/29 Deiva Rajasingam <dr.subscribe / gmail.com>:
> I am writing a Ruby script to accept a user's input which will be used
> as a password later on. The user input it taken using STDIN.getc. Since
> it is a password input, when the user enters the characters on the
> keyboard, the entered characters are not displayed and each character is
> obscured by displaying an asterix (*).
>
> The code snippet is shown below.
>
> ---------START---------
> def TestFunc
> =C2=A0myPassword =3D ""
>
> =C2=A0print "Password: "
> =C2=A0myPassword =3D getPassword
>
> =C2=A0print "My password: #{myPassword}\n"
> end
>
> def read_char
> =C2=A0system "stty raw -echo"
> =C2=A0ch =3D STDIN.getc
> ensure
> =C2=A0system "stty -raw echo"
> =C2=A0return ch
> end
>
> def getPassword
> =C2=A0password =3D ""
> =C2=A0input =3D ""
> =C2=A0isValidLastChar =3D 1
> =C2=A0invalidCharacterDetected =3D 0
>
> =C2=A0while (password =3D=3D "") || (password !=3D "" && input !=3D "\r")
> =C2=A0 =C2=A0char =3D read_char
> =C2=A0 =C2=A0input =3D char.chr
> =C2=A0 =C2=A0if input =3D=3D "\r"
> =C2=A0 =C2=A0 =C2=A0next
> =C2=A0 =C2=A0end
>
> =C2=A0 =C2=A0if char =3D=3D 127 =C2=A0 =C2=A0 =C2=A0 =C2=A0# backspace ch=
aracter pressed
> =C2=A0 =C2=A0 =C2=A0if password !=3D ""
> =C2=A0 =C2=A0 =C2=A0 =C2=A0password =3D password.chop
> =C2=A0 =C2=A0 =C2=A0 =C2=A0print "\b \b"
> =C2=A0 =C2=A0 =C2=A0end
> =C2=A0 =C2=A0elsif input !=3D "" && input[0] > 32 && input[0] < 127
> =C2=A0 =C2=A0 =C2=A0print "*"
> =C2=A0 =C2=A0 =C2=A0password =3D password + input
> =C2=A0 =C2=A0end
> =C2=A0end
>
> =C2=A0print "\n"
> =C2=A0return password
> end
> ----------END----------
>
> For this code, if I entered "1234" (without the quotes), followed by the
> F1 key, the PageUp key, the Right arrow key and finally pressed Enter, I
> see the following output on the screen:
>
> -----SCREEN OUTPUT-----
>
> [root@morpheus ~]# irb
> irb(main):001:0> load "TestRuby.rb"
> =3D> true
> irb(main):002:0> testStub
> Password: ***********
> My password: 1234[11~[5~[C
> =3D> nil
> irb(main):004:0>
>
> -----------------------
>
> Observe the printed output.
> 1 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> displayed as 1
> 2 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> displayed as 2
> 3 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> displayed as 3
> 4 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> displayed as 4
> F1 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0-> displayed as [11~
> PgUp =C2=A0 =C2=A0 =C2=A0 =C2=A0-> displayed as [5~
> Right arrow -> displayed as [C
>
> I am finding it difficult to figure out a way to ignore/process special
> keys (F1-F12, Up/Down/Left/Right, PgUp, PgDn, Home, End, etc.).
>
> Any suggestions or help?
Try Kernel#select like this:

def read_char
 system "stty raw -echo "
 ch =3D STDIN.getc
 if ch.chr=3D=3D27.chr
    STDIN.getc while(select([STDIN],nil,nil,0))
 end
ensure
 system "stty -raw echo "
 return ch
end

Regards,

Park Heesob