Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

CLI must not echo password

by vegasjoe (Sexton)
on Jan 19, 2005 at 00:28 UTC ( #423223=perlquestion: print w/replies, xml ) Need Help??

vegasjoe has asked for the wisdom of the Perl Monks concerning the following question:

I want to prompt a user for a password, but donít want what the user types to be echoed on the screen:
How can I do this?
This is no good.
print "enter password"; $pwd=<>;

Replies are listed 'Best First'.
Re: CLI must not echo password
by Corion (Patriarch) on Jan 19, 2005 at 07:24 UTC

    This is a FAQ:

    Q:\>perldoc -q password Found in S:\OS\OSP\OSPI\perl-5.8\5.8.2\lib\pod\perlfaq8.pod
    How do I ask the user for a password?

    (This question has nothing to do with the web. See a different FAQ for that.)

    There's an example of this in "crypt" in perlfunc). First, you put the terminal into "no echo" mode, then just read the password normally. You may do this with an old-style ioctl() function, POSIX terminal control (see POSIX or its documentation the Camel Book), or a call to the stty program, with varying degrees of portability.

    You can also do this for most systems using the Term::ReadKey module from CPAN, which is easier to use and in theory more portable.

    use Term::ReadKey; ReadMode('noecho'); $password = ReadLine(0);
Re: CLI must not echo password
by Tanktalus (Canon) on Jan 19, 2005 at 00:34 UTC

    I did something like this:

    our $stdin; our $origMode; our $isWindows = 0; eval q{ use Win32::Console $stdin = new Win32::Console STD_INPUT_HANDLE; $origMode = $stdin->Mode(); $isWindows = 1; }; sub getPassword { my $pr; my $required; if (@_) { $pr = shift || "Password"; $required = shift || undef; } else { $pr = "Password"; $required = 1; } my $password; until ($password) { print $pr, ": "; # if we don't have Term::ReadKey, skip it. my $isReadmode = 0; eval q{ use Term::ReadKey; ReadMode(2); $isReadmode = 1; }; # if that didn't work, try Windows. eval q{ $stdin->Mode(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | +ENABLE_MOUSE_INPUT); } if $@ and $isWindows; chomp($password = <STDIN>); if ($isReadmode) { eval { ReadMode(0); print "\n"; # only needed if readmode was successful. }; } elsif ($isWindows) { $stdin->Mode($origMode); } last unless $required; # if not required, just skip checks. unless (length ($password) > 5) { $password = undef; print "Too short. "; next; } } $password; }

    Not quite foolproof, but it was sufficient for me. As you can see, I got this working (good enough) on both unix and windows - but never tried Mac, mainframes, or PDAs. YMMV.

Re: CLI must not echo password
by foil (Sexton) on Jan 19, 2005 at 05:34 UTC
    Check out Term::ReadKey Readmode 2
      Term::ReadKey is the only solution that I could get to work. It is unfortunate that it needs a non-standard module. Here's my code:
      use Term::ReadKey; print 'Enter Username: '; my $user = <STDIN>; chomp $user; print "Enter Password: "; ReadMode ('noecho'); my $pass = <STDIN>; chomp $pass; ReadMode ('restore'); print "\n";
      Update: link to kobesearch since search.cpan is down
Re: CLI must not echo password
by TheDamian (Priest) on Jan 19, 2005 at 22:09 UTC
    Another alternative is IO::Prompt:
    use IO::Prompt; $pwd = prompt "enter password: ", -echo=>"";
    or, better still, echo the password with stars:
    use IO::Prompt; $pwd = prompt "enter password: ", -echo=>"*";
      Ooh, I nearly got excited about that, but it also isn't a standard module and needs Term::ReadKey as well anyway. The code does look cleaner though.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://423223]
Approved by Errto
Front-paged by tye
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (3)
As of 2022-06-26 20:51 GMT
Find Nodes?
    Voting Booth?
    My most frequent journeys are powered by:

    Results (86 votes). Check out past polls.