bash 从 python 脚本调用别名命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32739635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling alias Command from python script
提问by Balaji Spades
I need to run an OpenFOAM command by automatized python script.
我需要通过自动化的 python 脚本运行 OpenFOAM 命令。
My python code contains the lines
我的 python 代码包含这些行
subprocess.Popen(['OF23'], shell=True)
subprocess.Popen(['for i in *; do surfaceConvert $i file_path/$i.stlb; done', shell=True)
where OF23 is a shell command is defined in alias as
其中 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'
This script runs the OpenFOAM command in terminal and the file_path defines the stl files which are converted to binary format
此脚本在终端中运行 OpenFOAM 命令,file_path 定义了转换为二进制格式的 stl 文件
But when I run the script, I am getting 'OF23' is not defined.
但是当我运行脚本时,我得到 'OF23' 未定义。
How do I make my script to run the alias command and also perform the next OpenFOAM file conversion command
如何让我的脚本运行别名命令并执行下一个 OpenFOAM 文件转换命令
回答by PM 2Ring
That's not going to work, even once you've resolved the alias
problem. Each Python subprocess.Popen
is run in a separate subshell, so the effects of executing OF23
won't persist to the second subprocess.Popen
.
即使您解决了alias
问题,这也行不通。每个 Pythonsubprocess.Popen
都在单独的子 shell 中运行,因此执行的效果OF23
不会持续到第二个subprocess.Popen
.
Here's a brief demo:
这是一个简短的演示:
import subprocess
subprocess.Popen('export ATEST="Hello";echo "1 $ATEST"', shell=True)
subprocess.Popen('echo "2 $ATEST"', shell=True)
output
输出
1 Hello
2
So whether you use the alias, or just execute the aliased commands directly, you'll need to combine your commands into one subprocess.Popen
call.
因此,无论您使用别名,还是直接执行别名命令,您都需要将您的命令组合到一个subprocess.Popen
调用中。
Eg:
例如:
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)
I've used a triple-quoted string so I can insert linebreaks, to make the shell commands easier to read.
我使用了一个三引号字符串,所以我可以插入换行符,使 shell 命令更易于阅读。
Obviously, I can't test that exact command sequence on my machine, but it shouldwork.
显然,我无法在我的机器上测试那个确切的命令序列,但它应该可以工作。
回答by Michael Jaros
You need to issue shopt -s expand_aliases
to activate alias expansion. From bash(1)
:
您需要发出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 [...]
当 shell 不是交互式时,别名不会被展开,除非使用 shopt [...] 设置 expand_aliases shell 选项
If that does not help, check if the shell executed from your Python program is actually Bash (e.g. by echoing $BASH
).
如果这没有帮助,请检查从您的 Python 程序执行的 shell 是否实际上是 Bash(例如通过 echoing $BASH
)。
回答by jfs
If your command may use bash-isms then you could pass executable
parameter otherwise /bin/sh
is used. To expand aliases, you could use @Michael Jaros' suggestion:
如果您的命令可能使用 bash-isms,那么您可以传递executable
参数,否则/bin/sh
使用。要扩展别名,您可以使用@Michael Jaros 的建议:
#!/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')
If you already have a working bash-script then just call it as is.
如果您已经有一个可用的 bash 脚本,那么就按原样调用它。
Though to make it more robust and maintainable, you could convert to Python parts that provide the most benefit e.g., here's how you could emulate the for-loop:
虽然为了使其更健壮和可维护,您可以转换为提供最大好处的 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)])
It allows filenames to contain shell meta-characters such as spaces.
它允许文件名包含 shell 元字符,例如空格。
To configure the environment for a child process, you could use Popen's env
parameter e.g., env=dict(os.environ, ENVVAR='value')
.
要为子进程配置环境,您可以使用 Popen 的env
参数,例如env=dict(os.environ, ENVVAR='value')
.
It is possible to emulate source
bash command in Pythonbut you should probably leave the parts that depend on it in bash-script.
可以在 Python 中模拟source
bash 命令,但您可能应该将依赖于它的部分留在 bash-script 中。