2010-04-21 11 views
13

मैं पर्ल में एक इंटरैक्टिव शैल स्क्रिप्ट बनाने की कोशिश कर रहा हूं।पर्ल में प्रवेश के इंतजार किए बिना मैं उपयोगकर्ता इनपुट कैसे प्राप्त कर सकता हूं?

केवल उपयोगकर्ता इनपुट मैं मिल सकती है निम्नलिखित:

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

लेकिन इस उपयोगकर्ता हमेशा परिवर्तनों को प्रभावी करने के लिए एंटर दबाएं चाहिए। बटन दबाए जाने के तुरंत बाद प्रोग्राम कैसे आगे बढ़ सकता है?

उत्तर

16

perlfaq8 के जवाब से How do I read just one key without waiting for a return key? लिए: नियंत्रण इनपुट बफरिंग


उल्लेखनीय प्रणाली पर निर्भर मामला है। कई प्रणालियों पर, आप केवल stty कमांड का उपयोग कर सकते हैं जैसा कि perlfunc में 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 से ReadKey मॉड्यूल एक आसान से उपयोग इंटरफ़ेस है कि बाहर बमबारी प्रत्येक कुंजी के लिए stty के तुलना में अधिक कुशल होना चाहिए प्रदान करता है। इसमें विंडोज के लिए सीमित समर्थन भी शामिल है।

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

हालांकि, कोड का उपयोग करने के लिए आपके पास एक काम कर रहे सी संकलक की आवश्यकता है और इसे एक सीपीएएन मॉड्यूल बनाने और स्थापित करने के लिए उपयोग कर सकते हैं। मानक POSIX मॉड्यूल का उपयोग करके एक समाधान यहां दिया गया है, जो पहले से ही आपके सिस्टम पर है (मान लें कि आपका सिस्टम POSIX का समर्थन करता है)।

use HotKey; 
$key = readkey(); 

और यहाँ हॉटकी मॉड्यूल है, जो 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; 
+0

मैं पहली विधि (साथ ही दूसरे से कुछ) का उपयोग करने में सक्षम था: टीटीवी खोलना, इसे चरित्र ब्रेक पर सेट करना, और उसके बाद केवल 1 वर्ण को पकड़ने के लिए सिस्रेड का उपयोग करना – Lathan

5

आप एक कीप्रेस की जांच के लिए Term::ReadKey मॉड्यूल का उपयोग कर सकते हैं।

संबंधित मुद्दे

 संबंधित मुद्दे