如何在管道输入到 Perl 脚本后读取密码行
How to read password line after pipe input to Perl script
我正在尝试读取 STDIN
然后获取用户输入行而不在终端中显示它。
Term::ReadKey
与 ReadMode('noecho')
的解决方案将不起作用,因为它使用 <STDIN>
,如果它不为空,它会立即获取(应该是文件的内容,例如管道数据)作为 输入 而实际上不起作用:
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 系统并且输入可见...
所以我找到了非常简单的解决方案:
将 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
我正在尝试读取 STDIN
然后获取用户输入行而不在终端中显示它。
Term::ReadKey
与 ReadMode('noecho')
的解决方案将不起作用,因为它使用 <STDIN>
,如果它不为空,它会立即获取(应该是文件的内容,例如管道数据)作为 输入 而实际上不起作用:
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 系统并且输入可见...
所以我找到了非常简单的解决方案:
将 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