Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Perl脚本启动pdf查看器_Perl_Daemon - Fatal编程技术网

从Perl脚本启动pdf查看器

从Perl脚本启动pdf查看器,perl,daemon,Perl,Daemon,我必须从Perl脚本启动pdf查看器。观众应该 从父进程和运行父进程的终端分离。如果我关闭父级或终端 查看器仍应保持运行。我考虑了三种方法(使用evice作为pdf查看器命令): 使用系统和sh: system 'evince test.pdf &'; 使用fork(): 使用Proc::Daemon: use Proc::Daemon; my $daemon = Proc::Daemon->new( work_dir => '/tmp/evince',

我必须从Perl脚本启动pdf查看器。观众应该 从父进程和运行父进程的终端分离。如果我关闭父级或终端 查看器仍应保持运行。我考虑了三种方法(使用
evice
作为pdf查看器命令):

  • 使用
    系统
    sh

    system 'evince test.pdf &';
    
  • 使用
    fork()

  • 使用
    Proc::Daemon

    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';
    }
    
  • 这些方法之间有什么区别?你会推荐哪种方法

    system 'evince test.pdf &';
    
    根据我的经验,这很可能是:

    system 'evince $pdf_file &';
    
    如果用户输入的是
    $pdf\u文件
    ,那么我们就会得到shell注入错误,比如传入一个名为
    $(rm-rf/)
    的pdf名称,甚至只是
    ;rm-rf/
    。如果名字里有空格呢?好吧,如果你引用它,你可以避免所有这些,对吗

    system 'evince "$pdf_file" &';
    
    嗯,不,现在我要做的就是给你一个文件名
    “rm-rf”/
    。如果我的pdf文件名称中有双引号呢?您可以使用单引号,但是如果文件名中有单引号,那么同样的问题也会出现,而且shell注入也不难。您可以想出一个精心设计的shellify函数,它正确地引用字符串all,以便shell可以取消引用它并返回到原始条目。。。但这似乎比你的其他选择要做的工作多得多,而这两个选择都没有遇到这些问题

    $SIG{CHLD} = "IGNORE"; #reap children as they complete
    my $pid = fork();
    if ( $pid == 0 ) {
        exec 'evince', 'test.pdf';
    }
    
    设置一个全局的
    $SIG{CHLD}
    既好又容易。。。除非你需要在其他孩子死后处理他们。所以只有你才能知道这是否可以接受。而且,根据我的经验,甚至不总是这样。我曾经被这一次咬过——虽然很少。我将其与一个应用程序混合在一起,该应用程序在其他地方使用并设法破坏了AE的子流程处理。(如果您将其与任何事件系统混合使用,可能也会出现同样的情况,我只是碰巧使用了AE。)

    此外,还缺少stdout和stderr重定向以及stdin重定向。这很容易添加-在您的if中,在执行之前,只需根据需要关闭并重新打开文件句柄,例如:

    close STDOUT; open STDOUT, '>', '/dev/null';
    close STDERR; open STDERR, '>', '/dev/null';
    close STDIN;  open STDIN,  '<', '/dev/null';
    
    关闭STDOUT;打开标准输出“>”,“/dev/null”;
    关闭STDERR;打开STDERR“>”,“/dev/null”;
    
    关闭STDIN;打开STDIN,'如果这可能与
    nohup
    setsid
    命令有关,那将很有趣
    close STDOUT; open STDOUT, '>', '/dev/null';
    close STDERR; open STDERR, '>', '/dev/null';
    close STDIN;  open STDIN,  '<', '/dev/null';