2012-11-09 14 views
5

私はTerm :: ReadLine :: Gnuを使用しており、シグナルハンドリングの問題が発生しています。以下のスクリプトとTERMシグナルがスクリプトに送られた場合、 Enterキーが押された後にまでTERMシグナルのハンドラはトリガされません。 Term :: ReadLineを使う:これは発生しません。Perl Term :: ReadLine :: Gnuシグナルハンドリングの問題

私はTerm :: ReadLine :: Gnuには独自の内部シグナルハンドラがありますが、正直言って私はそれらを扱う方法を失っています。

http://search.cpan.org/~hayashi/Term-ReadLine-Gnu-1.20/Gnu.pm#Term::ReadLine::Gnu_Variablesは、rl_catch_signals変数を0に設定しようとしましたが、役に立たなかったことを確認しました。理想的には、私はGnuシグナルハンドラを使って作業したいと思いますが、私もそれらを無効にするために解決します。

具体的には、入力キーが押されるのを待つのではなく、信号が受信された後にトリガーする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 /'は何をすべきですか?あなたの2つのパイプの間に何もないので、正規表現はどんなものとも一致するので、!〜は常に偽になることに注意してください。 – Tanktalus

+0

ysthは別の投稿でこの質問に答えるのを手伝ってくれましたhttp://stackoverflow.com/questions/13332908/termreadline-i-need-to-hit-the-up-arrow-twice-to-retrieve-history T:R:Gはデフォルトで追加ヒストリを行います。私はそれを削除します。 –

答えて

3

これは、Perlのデフォルト信号の偏執的な取り扱いにある - readlineコールを開始する前に舞台裏で、perlのブロックSIGTERM、それが終了していますときにそれを復元します。詳細については、Deferred Signals in perlipcを参照してください。

Term::ReadLine::Perlは、これらの問題を知り、それらを処理するperlのIOを使用するため、このバグは表示されません。 Term::ReadLine::GnuはCライブラリを使用しています。

次の2つの方法のいずれかでこれを回避することができます。

  1. はのように、スクリプトを実行する前にunsafeに環境変数PERL_SIGNALSを設定します。

    bash$ PERL_SIGNALS=unsafe perl readline-test.pl 
    

    注、BEGIN { $ENV{PERL_SIGNALS} = "unsafe"; }ではありませんPerl自体が起動する前に設定する必要があります。

  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; }; 
    

    どちらも上記のは、Linuxで動作するようです。 Windowsやその他のユニークでは話せません。また、上記の両方には危険が伴います。詳しくはperlipcを参照してください。

関連する問題