使用 python 子进程运行 GNU 并行命令

Posted

技术标签:

【中文标题】使用 python 子进程运行 GNU 并行命令【英文标题】:Running a GNU parallel command using python subprocess 【发布时间】:2021-11-10 20:43:23 【问题描述】:

这是一个简单的 GNU 并行命令,它在名为“example_i”的现有目录中创建一个名为“example_i.txt”的文件。它这样做了四次,对于 i 从 1 到 4,每个核心一个作业:

parallel -j 4 'cd example_ && touch example_.txt' ::: 1..4

我知道,这不是很令人兴奋。当我尝试使用 subprocess 模块通过 python (v3.9) 运行时出现问题,如下所示:

import subprocess
cmd = "parallel -j 4 'cd example_ && touch example_.txt' ::: 1..4"
subprocess.run(cmd, shell=True)

执行此操作时出现此错误:

/bin/sh: 1: cd: can't cd to example_1..4

看起来像使用 python 子进程调用,bash 没有作为 GNU 并行命令正确触发调用。相反,它明确地替换了1..4,而不是将其分成四个工作。

我也尝试过使用不太可取的os.system(cmd) 语法并返回相同的错误。

PS:就上下文而言,这个问题源于我试图使用UQpy(特别是RunModel module)对交给我的 Fortran 代码进行不确定性量化。虽然这与问题没有直接关系,但它是相关的,因为我想知道如何使用 这些 工具使其工作,因为我无权更改它们。

【问题讨论】:

我认为您要么需要确保subprocess.run() 使用bash,要么通过将1..4 替换为1 2 3 4 来避免"bashisms" 【参考方案1】:

根据@Mark Setchell 的评论,在documentation for subprocess 中可以看到bash 似乎在POSIX 上默认不使用。这可以通过将我的 python 代码 sn-p 重写为:明确告诉 subprocess 使用 bash 来解决:

import subprocess
cmd = "parallel -j 4 'cd example_ && touch example_.txt' ::: 1..4"
subprocess.run(cmd, shell=True, executable='/bin/bash')

需要注意的是,虽然executable 参数在这里被用在subprocess.run() 调用中,但它并不是这个类的直接一部分。 executable 参数实际上是 subprocess.Popen() 类的一部分,但 subprocess.run() 可以通过 **other_popen_kwargs 参数访问它。

【讨论】:

以上是关于使用 python 子进程运行 GNU 并行命令的主要内容,如果未能解决你的问题,请参考以下文章

Python 子进程返回错误的退出代码

并行运行多个子进程 - python 2.7

在python中控制用于调用外部命令的子进程数

Python线程化多个bash子进程?

如果 Screen 被分离,GNU Screen 中的 Python 最终会变得空闲

使用python子进程运行shell命令[重复]