[英]How can I get user input without waiting for enter in Perl?
I am trying to make an interactive shell script in Perl. 我试图在Perl中创建一个交互式shell脚本。
The only user input I can find is the following: 我能找到的唯一用户输入如下:
$name = <STDIN>;
print STDOUT "Hello $name\n";
But in this the user must always press enter for the changes to take effect. 但在此,用户必须始终按Enter键才能使更改生效。 How can I get the program to proceed immediately after a button has been pressed? 如何在按下按钮后立即启动程序?
From perlfaq8 's answer to How do I read just one key without waiting for a return key? 从perlfaq8的答案我怎么只读一个键而不等待返回键? : :
Controlling input buffering is a remarkably system-dependent matter. 控制输入缓冲是一个非常依赖于系统的问题。 On many systems, you can just use the stty command as shown in getc in perlfunc, but as you see, that's already getting you into portability snags. 在许多系统上,您只需使用stty命令,如percunc中的getc所示,但正如您所见,这已经让您陷入可移植性障碍。
open(TTY, "+</dev/tty") or die "no tty: $!";
system "stty cbreak </dev/tty >/dev/tty 2>&1";
$key = getc(TTY); # perhaps this works
# OR ELSE
sysread(TTY, $key, 1); # probably this does
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
The Term::ReadKey module from CPAN offers an easy-to-use interface that should be more efficient than shelling out to stty for each key. CPAN的Term :: ReadKey模块提供了一个易于使用的界面,该界面应该比为每个密钥发出stty更高效。 It even includes limited support for Windows. 它甚至包括对Windows的有限支持。
use Term::ReadKey;
ReadMode('cbreak');
$key = ReadKey(0);
ReadMode('normal');
However, using the code requires that you have a working C compiler and can use it to build and install a CPAN module. 但是,使用代码要求您具有可用的C编译器,并且可以使用它来构建和安装CPAN模块。 Here's a solution using the standard POSIX module, which is already on your system (assuming your system supports POSIX). 这是使用标准POSIX模块的解决方案,该模块已经在您的系统上(假设您的系统支持POSIX)。
use HotKey;
$key = readkey();
And here's the HotKey module, which hides the somewhat mystifying calls to manipulate the POSIX termios structures. 这里是HotKey模块,隐藏了操纵POSIX termios结构的有些神秘的调用。
# HotKey.pm
package HotKey;
@ISA = qw(Exporter);
@EXPORT = qw(cbreak cooked readkey);
use strict;
use POSIX qw(:termios_h);
my ($term, $oterm, $echo, $noecho, $fd_stdin);
$fd_stdin = fileno(STDIN);
$term = POSIX::Termios->new();
$term->getattr($fd_stdin);
$oterm = $term->getlflag();
$echo = ECHO | ECHOK | ICANON;
$noecho = $oterm & ~$echo;
sub cbreak {
$term->setlflag($noecho); # ok, so i don't want echo either
$term->setcc(VTIME, 1);
$term->setattr($fd_stdin, TCSANOW);
}
sub cooked {
$term->setlflag($oterm);
$term->setcc(VTIME, 0);
$term->setattr($fd_stdin, TCSANOW);
}
sub readkey {
my $key = '';
cbreak();
sysread(STDIN, $key, 1);
cooked();
return $key;
}
END { cooked() }
1;
您可以使用Term :: ReadKey模块来检查按键。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.