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

Posted

技术标签:

【中文标题】Python - 调用 perl 作为子进程 - 等待完成其后台进程并打印到 shell【英文标题】:Python - call perl as subprocess - wait for finish its background process and print to shell 【发布时间】:2021-11-29 15:45:25 【问题描述】:

我有一个 Perl 脚本,内部调用 system("something &")。如果我从 shell 运行它,我会调用脚本,然后使用wait 命令等待所有后台进程。

如何从 Python 调用此脚本并等待它生成的“后台”脚本完成?

我试过了

pipe = subprocess.Popen(["perl", "script.pl", "data1", "data2"], stdin=subprocess.PIPE)
pipe.communicate()

但它不会等待并在 perl 脚本完成后退出。

另一个问题是我不知道如何在运行时将后台进程的输出打印到 shell。

【问题讨论】:

你做 shell 做的事——在它自己的进程组中运行 perl 脚本,然后等待整个进程组(通过传递否定的 pgid 等待或它的 python 等效项)。我不太了解python,但this 似乎是一个开始。但请注意,如果 python 本身是从 bash 运行的,则 perl 脚本及其子脚本将在尝试访问终端时停止或出现错误。很多事情可能无法按预期工作。 这就是为什么shell本身在运行脚本时默认不这样做的原因。请注意,直接来自终端的perl -e "system qsleep 60 &"; wait 将等待sleep,但sh -c 'perl -e "system qsleep 60 &"; wait'不会 【参考方案1】:

我已经根据这个答案 How can I make Perl wait for child processes started in the background with system()? 更改 Perl 脚本来解决这个问题

我变了

system("something &") 

my $pid = fork();
if ($pid == -1) 
   print("Failed to fork");
   die;
 elsif ($pid == 0) 
   exec "something ";

并添加

while (wait() != -1) 

到脚本结束

【讨论】:

以上是关于Python - 调用 perl 作为子进程 - 等待完成其后台进程并打印到 shell的主要内容,如果未能解决你的问题,请参考以下文章

导入pyspark ETL模块并使用python子进程作为子进程运行时出错

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

在 Perl 中修改子进程的环境

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

Perl和操作系统交互:fork

使用 Python 子进程调用 cmd 并传递参数