2017-01-12 10 views
1

Perlスクリプトからpdfビューアを起動する必要があります。ビューアは、親プロセスと親プロセスが実行された端末から切り離されるようにしてください。 親または端末を閉じると、 ビューアは引き続き実行されます。 systemshを使用してPerlスクリプトからPDFビューアを開始

  1. fork()使用
    system 'evince test.pdf &'; 
    
  2. Proc::Daemonを使用して

    $SIG{CHLD} = "IGNORE"; #reap children as they complete 
    my $pid = fork(); 
    if ($pid == 0) { 
        exec 'evince', 'test.pdf'; 
    } 
    
  3. を:私は(PDFビューアコマンドとしてevinceを使用)の3つのアプローチを検討し

    use Proc::Daemon; 
    my $daemon = Proc::Daemon->new(
        work_dir  => '/tmp/evince', 
        child_STDOUT => '>>stdout.txt', 
        child_STDERR => '>>stderr.txt', 
    ); 
    my $pid = $daemon->Init(); 
    if ($pid == 0) { 
        exec 'evince', 'test.pdf'; 
    } 
    

これらのアプローチの違いは何ですか?どちらのアプローチをお勧めしますか?私の経験で

答えて

3
system 'evince test.pdf &'; 

、これは本当に可能性がある:

system 'evince $pdf_file &'; 

$pdf_fileは、ユーザーの入力であれば、私たちはそのようにも$(rm -rf /)のPDFファイル名を渡すかのようにシェル・インジェクションのバグを取得ちょうど;rm -rf /。名前にスペースがあるとどうなりますか?まあ、あなたがそれを引用すれば、すべてを避けることができますよね?

system 'evince "$pdf_file" &'; 

さて、私がしなければならないのは、ファイル名を";rm -rf "/にするだけです。そして、私のpdfにその名前の二重引用符があるとどうなりますか?一重引用符を使用することもできますが、ファイル名に一重引用符が含まれていれば同じ問題が発生します。シェル注入はそれほど難しくありません。シェルがそれを引用符で囲み、元のエントリに戻ることができるように文字列を適切に引用符で囲むような、緻密なshellify関数を思いつくことができます...しかし、それはあなたの他のオプションよりもはるかに多くの仕事のようですこれらの問題。あなたは、彼らが死ぬと他の子供たちを処理する必要がない限り、グローバル$SIG{CHLD}の設定

$SIG{CHLD} = "IGNORE"; #reap children as they complete 
my $pid = fork(); 
if ($pid == 0) { 
    exec 'evince', 'test.pdf'; 
} 

は...いいと簡単です。だからあなたはそれが受け入れ可能かどうかだけを知ることができます。そして、私の経験では、いつもそうでもない。私はこの1つに噛まれました - まれですが。他の場所でAnyEventを使用し、AEのサブプロセス処理を中断させたアプリケーションと混在させました。 (これを他のイベントシステムと混在させても同様のことが成り立ちますが、私はちょうどAEを使用していました)

また、stdoutとstderrのリダイレクトとstdinのリダイレクトがありません。あなたが必要と

close STDOUT; open STDOUT, '>', '/dev/null'; 
close STDERR; open STDERR, '>', '/dev/null'; 
close STDIN; open STDIN, '<', '/dev/null'; 

大した:、例えばあなたの場合、execの前に、ちょうど近くの内側やファイルハンドルを再オープン - それは追加するのは簡単十分です。しかし、Proc :: Daemonは、ある方向から別の方向に信号が届かないようにするために、さらにいくつかのことを設定します。これはあなたが得る必要がある深刻さに依存します。

私の目的のほとんどは、#2で十分であることがわかりました。私はいくつかのプロジェクトでProc :: Daemonに到達しましたが、それはa)モジュールのインストールを完全に制御でき、b)本当に重要です。 pdfビューアを起動することは、通常、このような場合はありません。

私は何もせずに1を避ける - 私はシェルインジェクションでかなりの痛みを覚えましたが、今はいつもシェルを避けようとしています。

+0

これが 'nohup'コマンドと' setsid'コマンドに関連していると面白いです –

関連する問題