簡體   English   中英

如何在不等待進入Perl的情況下獲得用戶輸入?

[英]How can I get user input without waiting for enter in Perl?

我試圖在Perl中創建一個交互式shell腳本。

我能找到的唯一用戶輸入如下:

 $name = <STDIN>;
 print STDOUT "Hello $name\n";

但在此,用戶必須始終按Enter鍵才能使更改生效。 如何在按下按鈕后立即啟動程序?

perlfaq8的答案我怎么只讀一個鍵而不等待返回鍵?


控制輸入​​緩沖是一個非常依賴於系統的問題。 在許多系統上,您只需使用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";

CPAN的Term :: ReadKey模塊提供了一個易於使用的界面,該界面應該比為每個密鑰發出stty更高效。 它甚至包括對Windows的有限支持。

use Term::ReadKey;
ReadMode('cbreak');
$key = ReadKey(0);
ReadMode('normal');

但是,使用代碼要求您具有可用的C編譯器,並且可以使用它來構建和安裝CPAN模塊。 這是使用標准POSIX模塊的解決方案,該模塊已經在您的系統上(假設您的系統支持POSIX)。

use HotKey;
$key = readkey();

這里是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM