从python脚本调用别名命令

时间:2015-09-23 12:28:42

标签: python bash shell subprocess openfoam

我需要通过自动化的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文件转换命令

3 个答案:

答案 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脚本中保留依赖它的部分。