从终端识别 Python 子进程
Identify Python Subprocess from terminal
我们开发了一个 python 函数,该函数使用 pdftoppm/pdftocairo 启动子进程调用以拆分 pdf 并将每个页面存储为单独的图像。假设一个文档有 10 页,它会创建 10 个单独的 png 文件,每个文件代表文档的页面。有没有办法使用 htop
或 ps -ef
命令从终端拦截进程?
如果您实际上 运行 通过子流程模块的流程,那么它应该显示为常规(子)流程,是的。
>>> from subprocess import run
>>> run('/usr/bin/cat')
将导致:
$ ps -u myuser
...
36456 pts/2 00:00:00 python3
36463 pts/2 00:00:00 cat
...
如果您的 Python 程序在您想要收获子进程时仍然 运行ning,最简单的解决方案可能是将 timeout
关键字参数传递给 Popen.wait()
或 Popen.communicate()
.
subprocs = []
for page in pdf.pages():
sub = subprocess.Popen(['pdftoppm', 'etc', '--page', str(page), filename])
subprocs.append(sub)
# some Python processing here while you wait for the subprocesses to run in the background?
# Then once you are done and only want to reap them before you continue
for sub in subprocs:
sub.wait(timeout=60)
当你在一个已经完成的子进程上wait
时,立即调用returns。当您 wait
在已经超过其超时的子进程上时,这也应该(大致)立即发生。所以最后的 for
循环应该有效地等待第一个尚未完成或超过其超时的子进程,然后迅速收获其余的。
如果您的 Python 程序已经完成执行并且您还有一堆子进程剩余 运行ning,您启动的子进程将是孤儿,它们将被重新设置为 PID 1 的子进程,所以您无法再检查父进程并确定它们是您的。如果它们都 运行 在没有其他进程在其中执行的特定目录中,这可能是隔离它们的好方法。 (在 subprocess.Popen()
中,您可以使用 cwd=path_to_dir
传入目录。)在 Linux 中,/proc
文件系统使您可以轻松地遍历进程树并检查各个进程。进程树中的 cwd
条目是指向进程所在目录的符号链接 运行ning.
from pathlib import Path
for proc in Path('/proc').iterdir():
if all(x.isdigit() for x in proc.name):
if proc/'cwd'.readlink() == '/path/to/dir':
print(proc)
遗憾的是,Path.readlink()
仅在 Python 3.9 中引入;如果您需要在具有旧 Python 版本的机器上使用它,请尝试更传统的 os.path
意大利面条:
import os
for proc in os.listdir('/proc'):
if all(x.isdigit() for x in proc):
if os.readlink(os.path.join('/proc', proc, 'cwd')) == '/path/to/dir':
print(proc)
请注意 /proc
不可移植,但由于您专门询问 Ubuntu,您应该可以使用此方法。
如果您不想 运行 特定目录中的子流程,如果您的流程相当独特,可能还有其他方法可以找到您的流程,或者使它们相当独特以便于这个。你的问题确实没有充分揭示你的代码或你的要求,无法知道什么对你有用。
也许您可以 运行 使用外部 timeout
命令的进程,然后就这样。 GNU Coreutils timeout
二进制文件是 Ubuntu 基本安装的一部分(但在其他一些类似 U*x 的系统上可能无法开箱即用)。
for page in pdf.pages():
subprocess.Popen(['timeout', '60', 'pdftoppm', 'etc', '--page', str(page), filename])
(以上显然是在疯狂猜测您正在 运行ning 的实际命令及其需要的参数。)
我们开发了一个 python 函数,该函数使用 pdftoppm/pdftocairo 启动子进程调用以拆分 pdf 并将每个页面存储为单独的图像。假设一个文档有 10 页,它会创建 10 个单独的 png 文件,每个文件代表文档的页面。有没有办法使用 htop
或 ps -ef
命令从终端拦截进程?
如果您实际上 运行 通过子流程模块的流程,那么它应该显示为常规(子)流程,是的。
>>> from subprocess import run
>>> run('/usr/bin/cat')
将导致:
$ ps -u myuser
...
36456 pts/2 00:00:00 python3
36463 pts/2 00:00:00 cat
...
如果您的 Python 程序在您想要收获子进程时仍然 运行ning,最简单的解决方案可能是将 timeout
关键字参数传递给 Popen.wait()
或 Popen.communicate()
.
subprocs = []
for page in pdf.pages():
sub = subprocess.Popen(['pdftoppm', 'etc', '--page', str(page), filename])
subprocs.append(sub)
# some Python processing here while you wait for the subprocesses to run in the background?
# Then once you are done and only want to reap them before you continue
for sub in subprocs:
sub.wait(timeout=60)
当你在一个已经完成的子进程上wait
时,立即调用returns。当您 wait
在已经超过其超时的子进程上时,这也应该(大致)立即发生。所以最后的 for
循环应该有效地等待第一个尚未完成或超过其超时的子进程,然后迅速收获其余的。
如果您的 Python 程序已经完成执行并且您还有一堆子进程剩余 运行ning,您启动的子进程将是孤儿,它们将被重新设置为 PID 1 的子进程,所以您无法再检查父进程并确定它们是您的。如果它们都 运行 在没有其他进程在其中执行的特定目录中,这可能是隔离它们的好方法。 (在 subprocess.Popen()
中,您可以使用 cwd=path_to_dir
传入目录。)在 Linux 中,/proc
文件系统使您可以轻松地遍历进程树并检查各个进程。进程树中的 cwd
条目是指向进程所在目录的符号链接 运行ning.
from pathlib import Path
for proc in Path('/proc').iterdir():
if all(x.isdigit() for x in proc.name):
if proc/'cwd'.readlink() == '/path/to/dir':
print(proc)
遗憾的是,Path.readlink()
仅在 Python 3.9 中引入;如果您需要在具有旧 Python 版本的机器上使用它,请尝试更传统的 os.path
意大利面条:
import os
for proc in os.listdir('/proc'):
if all(x.isdigit() for x in proc):
if os.readlink(os.path.join('/proc', proc, 'cwd')) == '/path/to/dir':
print(proc)
请注意 /proc
不可移植,但由于您专门询问 Ubuntu,您应该可以使用此方法。
如果您不想 运行 特定目录中的子流程,如果您的流程相当独特,可能还有其他方法可以找到您的流程,或者使它们相当独特以便于这个。你的问题确实没有充分揭示你的代码或你的要求,无法知道什么对你有用。
也许您可以 运行 使用外部 timeout
命令的进程,然后就这样。 GNU Coreutils timeout
二进制文件是 Ubuntu 基本安装的一部分(但在其他一些类似 U*x 的系统上可能无法开箱即用)。
for page in pdf.pages():
subprocess.Popen(['timeout', '60', 'pdftoppm', 'etc', '--page', str(page), filename])
(以上显然是在疯狂猜测您正在 运行ning 的实际命令及其需要的参数。)