下面是一个简单的GNU并行命令,它创建一个名为" example_i.txt"在名为"example_i"的现有目录中。对于i,它从1到4执行此操作四次,每个核心有一个作业:
parallel -j 4 'cd example_{} && touch example_{}.txt' ::: {1..4}
我知道,这不是很令人兴奋。当我尝试通过python (v3.9)使用subprocess模块运行这个时,问题出现了,如下所示:
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模块)对交给我的Fortran代码进行不确定性量化。虽然这与问题没有直接关系,但它是相关的,因为我想知道如何使用这些工具来获得此工作,因为我不能自由地更改它们。
遵循@Mark Setchell的评论,确实似乎bash
在POSIX上默认不使用,正如可以在子进程的文档中看到的那样。这是通过显式地告诉subprocess
通过重写我的python代码片段使用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
参数访问它。