Python - 使用 os.subprocess 调用带有嵌套命令的 shell 脚本
Python - using os.subprocess to call a shell script with nested commands
我正在利用 python 到 运行 顶级遗传算法,使用 OpenFOAM 优化 3D 飞机机翼几何形状以获得空气动力学性能。我是 运行ning Ubuntu 16.04、Python 3.6 和 OpenFOAM 5。我写了几个驻留在 OpenFOAM 案例目录(包含几何 STL 文件的目录)中的 shell 脚本、流体动力学参数和网格)。这些脚本执行重复的文件管理命令和 OpenFOAM 并行过程分解程序,以及生成 3D 网格和 运行 模拟的命令。 python 脚本应该完全位于不同的目录中,因为数百个(如果不是数千个)这些案例文件夹将作为遗传算法的后代生成。问题是使用 os.subprocess 调用这些 shell 脚本似乎会为脚本中的每个命令生成和终止 shell。例如,如果我的代码是(简短版):
#!/bin/bash
rm constant/polyMesh/*
rm constant/triSurface/*.eMesh
rm -rf 0.*
find -type d -name '*e-0*' -exec rm -r {} +
decomposePar (OpenFOAM utility)
我用以下命令调用所述脚本:
subprocess.Popen(['./shellScript'],cwd=r'./pathToDirectory')
我最终得到错误:
./shellScript: line #: decomposePar no such file or directory
如果 shell 试图在 case 目录以外的目录中执行 decomposePar
(它应该顺利执行),我可以看到这种情况发生的唯一方法。对于案例管理命令,似乎只有第一个命令有效。我已经抓取了堆栈溢出来解决这个问题,但我不确定我是否找到了一个。我尝试使用 os.chdir('casePath')
设置 python 脚本的工作目录,设置 cwd='casePath'
,以及其他几个我不太明白的 subprocess
参数!
我知道我可以将每个 shell 命令转录成 Python,但我发现由于 shell 命令的数量和更改的可能性,这将非常乏味将来这些 shell 脚本。我希望我的方法是模块化的并且足够健壮 运行 只有几个我可以根据需要修改的脚本。此外,在一天结束时,这个程序将被部署到一台超级计算机上。并行处理将发生在 OpenFOAM 的 C++ 级别,而不是 python,所以这不是我关心的问题之一。有什么办法可以做到这一点,我是否遗漏了一些非常明显的东西?请原谅我,因为计算机科学不是我的强项,我是一名航空航天工程师。谢谢!
TL;DR:在 shell 脚本开始时从 OpenFOAM 安装获取 bashrc
。
在对 OP 进行了一些挖掘之后,问题最初是包含 decomposePar
的目录不在 PATH
环境变量中。
除非你的PATH中有.
(这很危险,不要这样做),将当前目录更改为目录不会对查找decomposePar
有任何影响。在 shell 脚本中添加 decomposePar
的完整路径允许 decomposePar
为 运行.
示例:
#!/bin/bash
rm constant/polyMesh/*
rm constant/triSurface/*.eMesh
rm -rf 0.*
find -type d -name '*e-0*' -exec rm -r {} +
/full/path/to/decomposePar
但是,当处于 运行 时,它无法加载所需的共享库,因为 OpenFOAM 共享库目录不在 LD_LIBRARY_PATH
环境变量中。为了解决这个问题,OpenFOAM bashrc
文件是在脚本开头获取的。
示例:
#!/bin/bash
source /path/to/bashrc
rm constant/polyMesh/*
...
排序此文件正确设置 PATH
和 LD_LIBRARY_PATH
环境变量。
我正在利用 python 到 运行 顶级遗传算法,使用 OpenFOAM 优化 3D 飞机机翼几何形状以获得空气动力学性能。我是 运行ning Ubuntu 16.04、Python 3.6 和 OpenFOAM 5。我写了几个驻留在 OpenFOAM 案例目录(包含几何 STL 文件的目录)中的 shell 脚本、流体动力学参数和网格)。这些脚本执行重复的文件管理命令和 OpenFOAM 并行过程分解程序,以及生成 3D 网格和 运行 模拟的命令。 python 脚本应该完全位于不同的目录中,因为数百个(如果不是数千个)这些案例文件夹将作为遗传算法的后代生成。问题是使用 os.subprocess 调用这些 shell 脚本似乎会为脚本中的每个命令生成和终止 shell。例如,如果我的代码是(简短版):
#!/bin/bash
rm constant/polyMesh/*
rm constant/triSurface/*.eMesh
rm -rf 0.*
find -type d -name '*e-0*' -exec rm -r {} +
decomposePar (OpenFOAM utility)
我用以下命令调用所述脚本:
subprocess.Popen(['./shellScript'],cwd=r'./pathToDirectory')
我最终得到错误:
./shellScript: line #: decomposePar no such file or directory
如果 shell 试图在 case 目录以外的目录中执行 decomposePar
(它应该顺利执行),我可以看到这种情况发生的唯一方法。对于案例管理命令,似乎只有第一个命令有效。我已经抓取了堆栈溢出来解决这个问题,但我不确定我是否找到了一个。我尝试使用 os.chdir('casePath')
设置 python 脚本的工作目录,设置 cwd='casePath'
,以及其他几个我不太明白的 subprocess
参数!
我知道我可以将每个 shell 命令转录成 Python,但我发现由于 shell 命令的数量和更改的可能性,这将非常乏味将来这些 shell 脚本。我希望我的方法是模块化的并且足够健壮 运行 只有几个我可以根据需要修改的脚本。此外,在一天结束时,这个程序将被部署到一台超级计算机上。并行处理将发生在 OpenFOAM 的 C++ 级别,而不是 python,所以这不是我关心的问题之一。有什么办法可以做到这一点,我是否遗漏了一些非常明显的东西?请原谅我,因为计算机科学不是我的强项,我是一名航空航天工程师。谢谢!
TL;DR:在 shell 脚本开始时从 OpenFOAM 安装获取 bashrc
。
在对 OP 进行了一些挖掘之后,问题最初是包含 decomposePar
的目录不在 PATH
环境变量中。
除非你的PATH中有.
(这很危险,不要这样做),将当前目录更改为目录不会对查找decomposePar
有任何影响。在 shell 脚本中添加 decomposePar
的完整路径允许 decomposePar
为 运行.
示例:
#!/bin/bash
rm constant/polyMesh/*
rm constant/triSurface/*.eMesh
rm -rf 0.*
find -type d -name '*e-0*' -exec rm -r {} +
/full/path/to/decomposePar
但是,当处于 运行 时,它无法加载所需的共享库,因为 OpenFOAM 共享库目录不在 LD_LIBRARY_PATH
环境变量中。为了解决这个问题,OpenFOAM bashrc
文件是在脚本开头获取的。
示例:
#!/bin/bash
source /path/to/bashrc
rm constant/polyMesh/*
...
排序此文件正确设置 PATH
和 LD_LIBRARY_PATH
环境变量。