从 python 脚本调用别名命令

Calling alias Command from python script

我需要通过自动化 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' 未定义。

如何使我的脚本成为 运行 别名命令并同时执行下一个 OpenFOAM 文件转换命令

您需要发出 shopt -s expand_aliases 以激活别名扩展。来自 bash(1):

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt [...]

如果这没有帮助,请检查从您的 Python 程序执行的 shell 是否实际上是 Bash(例如通过回显 $BASH)。

这是行不通的,即使您已经解决了 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 命令更易于阅读。

显然,我无法在我的机器上测试确切的命令序列,但它应该 工作。

如果您的命令可能使用 bash-isms,那么您可以传递 executable 参数,否则使用 /bin/sh。要扩展别名,您可以使用 :

#!/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-script 中。