I have the following segment of a script which is supposed to prompt a user for password and then capture the password entered by the user.
The function is called in by another script and used to work without issue, the problem is that recently the script is not waiting for the user to input the password it and immediately the calling script is giving an error that null password is provided.
Can someone please help?
sub prompt_for_password
{
my $account_name = $_[0];
my $account_description = $_[1];
my $display_prompt = $_[2];
if ($display_prompt)
{
print STDERR "\n";
print STDERR "Please enter password for $account_description '$account_name': ";
}
$LINUX = -d "/initrd";
$SOLARIS = -d "/kernel";
if ($LINUX)
{
system "/bin/stty cbreak -echo </dev/tty >/dev/tty 2>&1";
}
if ($SOLARIS)
{
system "/bin/stty icanon -echo </dev/tty >/dev/tty 2>&1";
}
$password = <STDIN>;
if ($LINUX)
{
system "/bin/stty cbreak echo </dev/tty >/dev/tty 2>&1";
}
if ($SOLARIS)
{
system "/bin/stty icanon echo </dev/tty >/dev/tty 2>&1";
}
if ($display_prompt)
{
print STDERR "\n";
}
chomp($password);
return $password;
}
The reason must be that a "\n" or ENTER key is still in the stdin buffer by the time that it gets to $password = <STDIN>; which then it gets removed by chomp($password); returning null
Look what happens depending of how the script is called and what's in the STDIN
This is your subroutine in its own script, with minor modifications to display
#!/usr/bin/perl
# script: pass.pl
use strict;
use warnings;
sub prompt_for_password
{
my $account_name = $_[0];
my $account_description = $_[1];
my $display_prompt = $_[2];
if ($display_prompt)
{
print STDERR "\n";
print STDERR "Please enter password for $account_description \'$account_name\': ";
}
my $LINUX = -d "/initrd";
my $SOLARIS = -d "/kernel";
if ($LINUX)
{
system "/bin/stty cbreak -echo </dev/tty >/dev/tty 2>&1";
}
if ($SOLARIS)
{
system "/bin/stty icanon -echo </dev/tty >/dev/tty 2>&1";
}
my $password = <STDIN>;
if ($LINUX)
{
system "/bin/stty cbreak echo </dev/tty >/dev/tty 2>&1";
}
if ($SOLARIS)
{
system "/bin/stty icanon echo </dev/tty >/dev/tty 2>&1";
}
if ($display_prompt)
{
print STDERR "\n";
}
chomp($password);
return $password;
}
my $pass = prompt_for_password("My First Account", "no description", "What prompt");
print ">>>$pass<<<\n";
my $pass = prompt_for_password("My Second Account", "no description", "What prompt");
print ">>>$pass<<<\n";
chmod +x pass.pl
call it normally first and observe the output
./pass.pl
call it now with something in STDIN
echo -e "screw the user\n" | ./pass.pl
call it now with the equivalent of ENTER in the STDIN