我需要通过自动化的python脚本运行OpenFOAM命令。
我的python代码包含行
subprocess.Popen(['OF23'], shell=True)
subprocess.Popen(['for i in *; do surfaceConvert $i file_path/$i.stlb; done', shell=True)
其中OF23是shell命令,在别名中定义为
alias OF23='export PATH=/usr/lib64/openmpi/bin/:$PATH;export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib/:$LD_LIBRARY_PATH;source /opt/OpenFOAM/OpenFOAM-2.3.x/etc/bashrc'
此脚本在终端中运行OpenFOAM命令,file_path定义转换为二进制格式的stl文件
但是当我运行剧本时,我得到的是OF23'没有定义。
如何让我的脚本运行alias命令并执行下一个OpenFOAM文件转换命令
答案 0 :(得分:5)
即使您已解决alias
问题,也无法正常工作。每个Python subprocess.Popen
都在一个单独的子shell中运行,因此执行OF23
的效果不会持续到第二个subprocess.Popen
。
这是一个简短的演示:
import subprocess
subprocess.Popen('export ATEST="Hello";echo "1 $ATEST"', shell=True)
subprocess.Popen('echo "2 $ATEST"', shell=True)
<强>输出强>
1 Hello
2
因此,无论您是使用别名,还是直接执行别名命令,您都需要将命令合并到一个subprocess.Popen
调用中。
例如:
subprocess.Popen('''export PATH=/usr/lib64/openmpi/bin/:$PATH;
export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib/:$LD_LIBRARY_PATH;
source /opt/OpenFOAM/OpenFOAM-2.3.x/etc/bashrc;
for i in *;
do surfaceConvert $i file_path/$i.stlb;
done''', shell=True)
我使用了三引号字符串,因此我可以插入换行符,以便更容易阅读shell命令。
显然,我无法在我的机器上测试那个确切的命令序列,但它应工作。
答案 1 :(得分:4)
您需要发出shopt -s expand_aliases
来激活别名扩展。来自bash(1)
:
当shell不是交互式时,不会展开别名,除非使用shopt设置expand_aliases shell选项[...]
如果这没有帮助,请检查从Python程序执行的shell是否实际上是Bash(例如,通过回显$BASH
)。
答案 2 :(得分:1)
如果您的命令可能使用bash-isms,那么您可以传递executable
参数,否则使用/bin/sh
。要扩展别名,您可以使用@Michael Jaros' suggestion:
#!/usr/bin/env python
import subprocess
subprocess.check_call("""
shopt -s expand_aliases
OF23
for i in *; do surfaceConvert $i file_path/$i.stlb; done
"""], shell=True, executable='/bin/bash')
如果您已经有一个正常工作的bash脚本,那么只需按原样调用它。
虽然为了使其更加强大和可维护,但您可以转换为提供最大好处的Python部分,例如,这里是如何模拟for循环的:
#!/usr/bin/env python
import subprocess
for entry in os.listdir():
subprocess.check_call(['/path/to/surfaceConvert', entry,
'file_path/{entry}.stlb'.format(entry)])
它允许文件名包含shell元字符,例如空格。
要为子流程配置环境,您可以使用Popen的env
参数,例如env=dict(os.environ, ENVVAR='value')
。
可以emulate source
bash command in Python,但您应该在bash脚本中保留依赖它的部分。