2012-11-09 28 views
5

Term :: ReadLine :: Gnu kullanıyorum ve sinyal işleme ile ilgili bir sorun yaşadım. Aşağıdaki betik ve betiğe gönderilen bir TERM sinyali verildiğinde, TERM sinyalinin işleyicisi numaralı tuşa basıldıktan sonra 'a kadar tetiklenmez. Term :: ReadLine kullanarak: Perl bu olmaz.Perl Dönemleri :: ReadLine :: Gnu Sinyal İşleme Zorlukları

Term :: ReadLine :: Gnu'nun kendi dahili sinyal işleyicilerine sahip olduğunu okudum, ancak açıkçası onlarla nasıl çalışacağım konusunda bir kayıp yaşıyorum.

http://search.cpan.org/~hayashi/Term-ReadLine-Gnu-1.20/Gnu.pm#Term::ReadLine::Gnu_Variables, rl_catch_signals değişkenini 0 olarak ayarlamayı denedim, ancak bu yardımcı olmadı. İdeal olarak, Gnu sinyal işleyicileri ile çalışmak isterdim, ama ben de onları devre dışı bırakmaya razı olacağım.

Kesinlikle belirtmek gerekirse, enter tuşuna basılmasını beklemek yerine, sinyal alındıktan sonra tetiklemek için TERM işleyicisine ihtiyacım var.

Herhangi bir yardım veya tavsiye kesinlikle takdir edilmektedir!

#!/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

Bu bir arabellek sorunu olup olmadığını merak ediyorum. Bu yanıtı çözümden deneyin: http://stackoverflow.com/a/7603502/1791055 – titanofold

+1

'/ \ S || \ n /' ne yapması gerekiyor? :-) (Senin asıl sorununla ilgili değil, sadece fark ettim.) İki borunun arasında hiçbir şey olmadığı için, regex'in herşeyle eşleşeceğine dikkat et, böylece her zaman yanlış olur. – Tanktalus

+0

ysth, bu soruyu başka bir gönderide yanıtlamama yardımcı oldu http://stackoverflow.com/questions/13332908/termreadline-i-need-to-hit-the-up-arrow-twice-to-retrieve-history T: R: G, varsayılan olarak addhistory olarak gereksizdir. Onu çıkaracağım. –

cevap

3

Bu en sinyallerin paranoyak işlenmesini varsayılan Perl programının kaynaklanmaktadır - readline aramayı başlatmadan önce perde arkasında, perl blokları SIGTERM ve Bittiğinde onu geri yükler. Detaylar için bkz. Deferred Signals in perlipc.

Term::ReadLine::Perl, bu sorunlardan ve bunlarla ilgili anlaşmalardan haberdar olan perl'in IO'sunu kullanır, böylece bu hatayı bununla birlikte görmezsiniz. Term::ReadLine::Gnu, C kütüphanesini kullanmıyor, bu da öyle değil.

iki yöntemden biri ile bu çalışabilirsiniz:

  1. olduğu gibi komut dosyasını çalıştırmadan önce unsafe için ortam değişkeni PERL_SIGNALS ayarlayın:

    bash$ PERL_SIGNALS=unsafe perl readline-test.pl 
    

    Not, BEGIN { $ENV{PERL_SIGNALS} = "unsafe"; } değil yeterli, perl'in kendisi başlamadan önce ayarlanması gerekiyor.

  2. Kullanım POSIX sinyal fonksiyonları:

    #~ $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; }; 
    

    Hem yukarıdaki Linux çalışmıyor gibi görünüyor; Windows veya diğer birimler için konuşamaz. Ayrıca, yukarıdakilerin her ikisi de riskler ile birlikte gelir - ayrıntılar için perlipc bakın.

İlgili konular