从Perl脚本启动pdf查看器
我必须从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',
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';