3

I'm trying to read STDIN and then get user input line without displaying it in terminal.

The Term::ReadKey's solution with ReadMode('noecho') will not work because it uses <STDIN> and if it is not empty it immediately takes(that what is supposed to be file, e.g. piped data) as input and not actually works:

use warnings;
use strict;
use Term::ReadKey;

my $_stdin = <STDIN>;
print "Enter your password:\n";
ReadMode('noecho');
my $_pass = ReadLine(0); # This one uses <STDIN>!
ReadMode(0);
print "STDIN:\n$_stdin\nPassword:\n$_pass\n";

output:

$ echo "some data" | perl term-readkey.pl
Enter your password:
Use of uninitialized value $_pass in concatenation (.) or string at term-readkey.pl line 10, <STDIN> line 1. 
STDIN:
some data

Password:

The only solution that I come with is to use Term::ReadLine which seems not using <STDIN> as Term::ReadKey, but the problem is that output of the $_term->readline() is visible:

use warnings;
use strict;
use Term::ReadLine;

my $_stdin = <STDIN>;
my $_term = Term::ReadLine->new('term');
my $_pass = $_term->readline("Enter your password:\n");
print "STDIN:\n$_stdin\nPassword:\n$_pass\n";

output:

$ echo "some data" | perl term-readkey.pl
Enter your password:
25 # actually entered it, and its visible...
STDIN:
some data

Password:
25

There was a similar question, but the answer is working only on Unix'y systems and input is visible...

BladeMight
  • 2,670
  • 2
  • 21
  • 35

1 Answers1

4

So I've found solution, which was quite simple:

Using the Term::ReadKey's ReadMode with Term::ReadLine's term's IN, example:

use Term::ReadLine;
use Term::ReadKey;

my $_stdin = <STDIN>;
my $_term = Term::ReadLine->new('term');
ReadMode('noecho', $_term->IN);
my $_pass = $_term->readline("Enter your password:\n");
ReadMode(0, $_term->IN);
print "STDIN:\n$_stdin\nPassword:\n$_pass\n";

or(thanks to Ujin)

use Term::ReadLine;
use Term::ReadKey;

my $_stdin = <STDIN>;
my $term = Term::ReadLine->new('term');
my @_IO = $term->findConsole();
my $_IN = $_IO[0];
print "INPUT is: $_IN\n";
open TTY, '<', $_IN;
print "Enter your password:\n";
ReadMode('noecho', TTY);
my $_pass = <TTY>;
ReadMode(0, TTY);
close TTY;
print "STDIN:\n$_stdin\nPassword:\n$_pass\n";

outputs:

Enter your password:
     # here enter hiddenly
STDIN:
stdin input

Password:
paws
BladeMight
  • 2,670
  • 2
  • 21
  • 35