输入管道到Perl脚本后如何读取密码行

时间:2018-10-27 02:33:59

标签: perl pipe stdin

我正在尝试阅读STDIN,然后获取用户输入行而不在终端中显示它。

Term::ReadKey使用ReadMode('noecho')的解决方案将不起作用,因为它使用<STDIN>,如果不为空,则立即采用(应该是文件,例如管道数据) )作为 input ,实际上不起作用:

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";

输出:

$ 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:

我随附的唯一解决方案是使用Term::ReadLine,似乎没有将<STDIN>用作Term::ReadKey,但是问题在于$_term->readline()的输出是可见的:

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";

输出:

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

Password:
25

有一个similar question,但是答案仅在Unix'y系统上有效,并且输入是可见的...

1 个答案:

答案 0 :(得分:3)

所以我找到了解决方法,这很简单:

Term::ReadKey的ReadMode与Term::ReadLine的术语IN一起使用,例如:

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";

或(感谢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";

输出:

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

Password:
paws