如何获取在Perl脚本中执行的程序的PID

如何获取在Perl脚本中执行的程序的PID,perl,pid,Perl,Pid,说明如何在使用Perl的exec()时获取新进程的pid。pid甚至不会改变,所以您需要做的就是获取原始脚本的pid。但是,如果我将输出重定向到一个文件作为命令的一部分,这是不起作用的,我需要这样做 say "my pid is $$"; exec("childscript.pl"); # same pid 但如果我将输出重定向为命令的一部分: say "my pid is $$"; exec("childscript.pl > log.txt");

说明如何在使用Perl的
exec()
时获取新进程的pid。pid甚至不会改变,所以您需要做的就是获取原始脚本的pid。但是,如果我将输出重定向到一个文件作为命令的一部分,这是不起作用的,我需要这样做

say "my pid is $$";
exec("childscript.pl");                  # same pid
但如果我将输出重定向为命令的一部分:

say "my pid is $$";
exec("childscript.pl > log.txt");        # different pid, usually old pid + 1
exec("childscript.pl > log.txt 2>&1 &"); # same
然后新pid比旧pid高一个(这可能只是因为它们是连续繁殖的,不可靠)。我通过查看输出和在“childscript.pl”中插入
sleep30
来测试这一点,这样我就可以用
ps-e
查看它了


我的猜测是,重定向输出会导致一个新的进程进行编写。但是我需要程序的pid,我不能控制程序,除了我可以执行它。(它也需要在后台运行。)

当您使用单个参数调用
exec
(该参数包含shell元字符)时,perl会自动为您运行
sh-c ARG
。就你而言:

exec("childscript.pl > log.txt");
# really means:
exec("/bin/sh", "-c", "childscript.pl > log.txt");
也就是说,脚本将
sh
加载到当前正在运行的进程中,保持其PID。shell执行输出重定向,然后作为子进程(使用新的PID)运行
childscript.pl

有两种方法可以解决此问题:

  • 在Perl中执行输出重定向,不生成shell:

    open STDOUT, ">", "log.txt" or die "$0: log.txt: $!\n";
    exec "childscript.pl";
    die "$0: childscript.pl: $!\n";
    
  • 告诉shell也使用
    exec
    ,不要生成子进程:

    exec "exec childscript.pl > log.txt";
    die "$0: childscript.pl: $!\n";
    

  • 杰出的两种方法都有效。无论出于什么原因,有哪个更可取的吗?我想第二种方法依赖于shell有一个兼容的
    exec
    实现,但我想它在*NIXes中是一样的,因为它只有一行。@felvithe,涉及shell会调用更多的工作和更多可能出错的事情。始终选择移除不必要碎片的选项。