2012-11-09 10 views
5

मैं टर्म :: रीडलाइन :: जीएनयू का उपयोग कर रहा हूं और सिग्नल हैंडलिंग के साथ एक समस्या में भाग गया हूं। नीचे लिपि और स्क्रिप्ट को भेजे गए एक टीईआरएम सिग्नल को देखते हुए, टीईआरएम सिग्नल के लिए हैंडलर के बाद ट्रिगर नहीं किया गया है, एंटर कुंजी दबाया जाता है। टर्म :: रीडलाइन का उपयोग करना: पर्ल यह नहीं होता है।पर्ल टर्म :: रीडलाइन :: जीएनयू सिग्नल हैंडलिंग कठिनाइयों

मैंने पढ़ा है कि टर्म :: रीडलाइन :: जीएनयू का अपना आंतरिक सिग्नल हैंडलर है, लेकिन स्पष्ट रूप से मुझे उनके साथ काम करने के तरीके के नुकसान में है।

मैंने समीक्षा की है http://search.cpan.org/~hayashi/Term-ReadLine-Gnu-1.20/Gnu.pm#Term::ReadLine::Gnu_Variables rl_catch_signals चर को 0 पर सेट करने का प्रयास किया, लेकिन इससे मदद नहीं मिली। आदर्श रूप से, मैं जीएनयू सिग्नल हैंडलर के साथ काम करना चाहता हूं, लेकिन मैं उन्हें अक्षम करने के लिए भी व्यवस्थित हूं।

बिल्कुल विशिष्ट होने के लिए, मुझे एंटर कुंजी दबाए जाने के बजाय सिग्नल प्राप्त होने के बाद ट्रिगर करने के लिए TERM हैंडलर की आवश्यकता होती है।

कोई भी मदद या सलाह निश्चित रूप से सराहना की जाती है!

#!/usr/bin/perl 

use strict; 
use warnings; 
use Term::ReadLine; 

$SIG{TERM} = sub { print "I got a TERM\n"; exit; }; 

my $term = Term::ReadLine->new('Term1'); 
$term->ornaments(0); 
my $prompt = 'cmd> '; 
while (defined (my $cmd = $term->readline($prompt))) { 
    $term->addhistory($cmd) if $cmd !~ /\S||\n/; 
    chomp($cmd); 
    if ($cmd =~ /^help$/) { 
     print "Help Menu\n"; 
    } 
    else { 
     print "Nothing\n"; 
    } 
} 
+0

मुझे आश्चर्य है कि यह एक बफरिंग समस्या है या नहीं। इस उत्तर से समाधान आज़माएं: http://stackoverflow.com/a/7603502/1791055 – titanofold

+1

'/ \ S || \ n /' क्या करना है? :-) (आपके वास्तविक प्रश्न से संबंधित नहीं, मैंने अभी इसे देखा है।) ध्यान दें कि क्योंकि आपके दो पाइप के बीच कुछ भी नहीं है, रेगेक्स कुछ भी मेल खाएगा, इसलिए! ~ हमेशा झूठा होगा। – Tanktalus

+0

ysth ने मुझे इस प्रश्न का उत्तर किसी अन्य पोस्ट में उत्तर देने में मदद की http://stackoverflow.com/questions/13332908/termreadline-i-need-to-hit-the-up-arrow-twice-to-retrieve-history इसे पूरी तरह से बाहर कर देता है टी के रूप में अनिवार्य: आर: जी डिफ़ॉल्ट रूप से addhistory करता है। मैं इसे हटा दूंगा। –

उत्तर

3

इस पर्ल के लिए के संकेतों के पागल हैंडलिंग डिफ़ॉल्ट वजह से है - readline कॉल शुरू करने से पहले पर्दे के पीछे, पर्ल ब्लॉक SIGTERM और यह पुनर्स्थापित करता है इसके समाप्त होने पर। विवरण के लिए Deferred Signals in perlipc देखें।

Term::ReadLine::Perl पर्ल के आईओ का उपयोग करता है, जो इन मुद्दों के बारे में जानता है और उनके साथ सौदा करता है, इसलिए आपको इसके साथ यह बग नहीं दिखाई देता है। Term::ReadLine::Gnu सी लाइब्रेरी का उपयोग करता है, जो नहीं करता है, तो आप करते हैं।

आप इस के आसपास दो तरीकों में से एक के साथ काम कर सकते हैं:

  1. unsafe को वातावरण चर PERL_SIGNALS सेट स्क्रिप्ट चलाने से पहले, के रूप में:

    bash$ PERL_SIGNALS=unsafe perl readline-test.pl 
    

    ध्यान दें, BEGIN { $ENV{PERL_SIGNALS} = "unsafe"; } नहीं है पर्याप्त, इसे खुद को शुरू होने से पहले सेट करने की जरूरत है।

  2. उपयोग POSIX संकेत कार्य:

    #~ $SIG{TERM} = sub { print "I got a TERM\n"; exit; }; 
    use POSIX; 
    sigaction SIGTERM, new POSIX::SigAction sub { print "I got a TERM\n"; exit; }; 
    

    उपरोक्त दोनों लिनक्स में काम करने के लिए पसंद करते हैं; विंडोज या अन्य इकाइयों के लिए बात नहीं कर सकते हैं। इसके अलावा, उपरोक्त दोनों जोखिमों के साथ आते हैं - विवरण के लिए perlipc देखें।

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