Hiding User Input
I'm trying to get a script that works both in a native windows shell and a cygwin shell (via ssh) that prompts for and reads a password entered by the user. So far, I have tried the following methods:
- using Term::ReadKey and setting ReadMode to 'noecho'
- RESULT: returns an error
GetConsoleMode failed
and quits
- RESULT: returns an error
- using Term::ReadPassword::Win32
- RESULT: hangs and never offers a prompt or reads input
- using IO::Prompt
- RESULT: returns an error
Cannot write to terminal
and quits
- RESULT: returns an error
- using Term::InKey
- RESULT: returns an error
Not implemented on MSWin32: The handle is invalid
and quits
- RESULT: returns an error
All of these work in a native Windows shell (command prompt or power shell), but none of them work when I'm in an ssh session to the server.
Really, that's what I'm most interested in, getting it to work in the remote ssh session.
I'm getting ssh via cygwin installed on the Windows server (2003 R2). I'm using strawberry perl and not the cygwin perl (cygwin perl 开发者_如何学JAVAbreaks other perl scripts I need to run natively in Windows, not via ssh).
My best guess is that cygwin+Windows is screwing with strawberry perl enough that it can't tell what kind of environment it is in. I'm looking into alternative sshd+Windows solutions to explore this.
These are all the methods I've been able to find in my searching. Does anybody else have any other methods for hiding user input they can suggest?
use Term::ReadKey;
print "Please enter your artifactory user name:";
$username = <STDIN>;
chomp($username);
ReadMode('noecho'); # don't echo
print "Please enter your artifactory password:";
$password = <STDIN>;
chomp($password);
ReadMode(0); #back to normal
print "\n\n";
I would try outputting the environment variables (%ENV) during the sessions that work, and then again during the sessions that don't. I find that, when dealing with terminal IO, you have to carefully tweak the "TERM" variable based on things like the $^O variable and $ENV{SESSIONNAME} (in Windows).
how about Term::ReadKey's ReadMode(4)? i've just used this in a personal project, having found the answer here
works on cygwin / win7, can't vouch for native windows shell however.
use strict;
use warnings;
use Term::ReadKey;
sub get_input {
my $key = 0;
my $user_input = "";
# disable control keys and start reading keys until enter key is pressed (ascii 10)
ReadMode(4);
while (ord($key = ReadKey(0)) != 10)
{
if (ord($key) == 127 || ord($key) == 8) {
# backspace / del was pressed. remove last char and move cursor back one space.
chop ($user_input);
print "\b \b";
} elsif (ord($key) < 32) {
# control characters, do nothing
} else {
$user_input = $user_input . $key;
print "*";
}
}
ReadMode(0);
return $user_input;
}
# variables
my $password = "";
my $username = "";
print "\nPlease input your username: ";
$username = get_input();
print "\nHi, $username\n";
print "\nPlease input your password: ";
$password = get_input();
精彩评论