Perl Term :: ReadKey不等待换行符

时间:2010-06-16 15:30:17

标签: perl

在perl脚本中,我试图接受输入而不阻塞并且没有回显输入的字符(脚本正在生成输出,我想要'热键'来改变它的行为)。

我得到了使用

use Term::ReadKey;
ReadMode( "cbreak", STDIN );
if($input = ReadKey($pause_time, STDIN)){
    #process input
}

但是一旦用户键入任何内容,脚本就会停止,直到输入换行符。我希望每个字符都能处理输入,而不必等待换行符。

2 个答案:

答案 0 :(得分:7)

这是一个小程序,可以满足我的需求:

#!/usr/bin/perl

use strict;
use warnings;

use Term::ReadKey;

ReadMode 4;
END { ReadMode 0 }

print <<EOS;
q to quit
b to print in binary
o to print in octal
d to print in decimal
x to print in hexadecimal
EOS

my $control = "d";
my $i       = 0;
while (1) {
    #use "if" if you want to have a buffer of commands
    #that will be processed one per second  
    while (defined (my $key = ReadKey(-1))) {
        exit 0          if $key eq 'q';
        $control = $key if $key =~ /^[bodx]$/;
    }
    printf "%$control\n", $i++;
    sleep 1;
}

答案 1 :(得分:2)

我打算将此作为对你自己'回答'的评论,但我决定需要更多空间。

cbreak相当于原始模式,除了cbreak不拦截控制序列如ctrl-c,ctrl-z等。它们都一次收集一个字符。两种模式之间的行为差​​异不是您的问题的根源。如果Chas的解决方案与您的预期相符,那么问题更可能与您在#process input行中编辑的内容有关。我已经评论过你的原始脚本工作得很好,如果我用一些简单的东西填充它,所以我可以看到它正在工作。例如,一个小修饰:

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

my ($char, $input, $pause_time);
ReadMode("cbreak");

# Collect all characters typed into $input
# and quit when '#' is typed.

$input = '';
while ($char = ReadKey($pause_time)) {
    last if $char eq '#';
    $input .= $char;
}

print "$input\n";

我不需要在结尾处点击“输入”,这样做不会做任何事情(除了将回车投入$input并且对字符串进行调整)。