在 Perl 中修改子进程的环境

Posted

技术标签:

【中文标题】在 Perl 中修改子进程的环境【英文标题】:Modifying the environment for a child process in Perl 【发布时间】:2015-04-21 23:37:32 【问题描述】:

我不确定为什么这不起作用,但也许我过于简单/过于复杂

我正在编写一个最终需要调用外部程序的 Perl 脚本。问题是,该程序需要修改版的 LD_LIBRARY_PATH 环境变量,以便找到一些供应商未在标准位置安装的库。

好的,环境在%ENV,可以重写,是吗?

我想如果我在父级中更改LD_LIBRARY_PATH,会影响子级的动态链接。

所以我有:

use Env qw(@LD_LIBRARY_PATH);
use IPC::System::Simple qw(capturex $EXITVAL);

# We need these to establish the call to rsq later
my ($rsqexe, $rsqhome, $suffix) = fileparse($config->rsq());
push @LD_LIBRARY_PATH, $rsqhome;

eval 
  $output = capturex(
    $config->rsq(),
    qq/"$source"/
  );
;

但是子进程死掉了,提示找不到共享库。

我该如何改进?

我确实需要在成功执行后检查$output的内容。

【问题讨论】:

尝试使用转储 $LD_LIBRARY_PATH 内容的包装器来包装您尝试执行的程序。将未知问题分成两半。如果您没有看到您希望看到的 $LD_LIBRARY_PATH,您可以朝一个方向看。如果您看到正确的 $LD_LIBRARY_PATH,但您的包装器无论如何都无法执行该程序,那么您将转向不同的方向。 感谢您的建议 - 您的方法发现了真正的问题(毕竟这与 LD_LIBRARY_PATH 无关) 【参考方案1】:
    eval 
      $output = capturex(
        $config->rsq(),
        qq/"$source"/
      );
    ;

问题出在这里:我没有检查 $@ 中的内容(或者 $EVAL_ERR 如果你是 use ENGLISH;

如果我有,我会发现问题出在引用 qq/"$source"/ - 因为 capturex() 调用 shell(这是所需的行为)引号打破了文件名(即test.pdf 存在,但""test.pdf"" 不存在)。

【讨论】:

对,应该是capturex($config->rsq(), $source)。使用capturex 的全部意义在于避免使用shell_quote 或像qq/"$source"/ 这样的错误引用解决方案。

以上是关于在 Perl 中修改子进程的环境的主要内容,如果未能解决你的问题,请参考以下文章

perl fork() exec() ,子进程变得狂野

Perl:关闭信号处理程序中的子进程管道挂起?

Python - 调用 perl 作为子进程 - 等待完成其后台进程并打印到 shell

管道被 Perl 中的子进程阻塞

Perl:当子/管道的文件句柄被别名时,关闭子进程失败

Perl 行为差异关闭由 open() 产生的子进程与 IPC::Open3