2

I need to run an OpenFOAM command by automatized python script.

My python code contains the lines

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

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

But when I run the script, I am getting 'OF23' is not defined.

How do I make my script to run the alias command and also perform the next OpenFOAM file conversion command

4

3 に答える 3

6

問題を解決したとしても、それはうまくいきませんalias。各 Pythonsubprocess.Popenは個別のサブシェルで実行OF23されるため、実行の効果は 2 番目のsubprocess.Popen.

簡単なデモを次に示します。

import subprocess

subprocess.Popen('export ATEST="Hello";echo "1 $ATEST"', shell=True)
subprocess.Popen('echo "2 $ATEST"', shell=True)

出力

1 Hello
2 

したがって、エイリアスを使用する場合でも、エイリアス化されたコマンドを直接実行する場合でも、コマンドを 1 つの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)

シェル コマンドを読みやすくするために、改行を挿入できるように、トリプル クォーテーションで囲まれた文字列を使用しました。

明らかに、私のマシンでその正確なコマンド シーケンスをテストすることはできませんが、動作するはずです。

于 2015-09-23T12:47:58.460 に答える
4

shopt -s expand_aliasesエイリアス展開を有効にするには、発行する必要があります。からbash(1):

シェルがインタラクティブでない場合、expand_aliases シェル オプションが shopt を使用して設定されていない限り、エイリアスは展開されません [...]

それでも問題が解決しない場合は、Python プログラムから実行されたシェルが実際に Bash であるかどうかを確認してください (例: echoing によって$BASH)。

于 2015-09-23T12:37:39.930 に答える
2

コマンドが 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')

すでに動作する 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)])

ファイル名にスペースなどのシェル メタ文字を含めることができます。

子プロセスの環境を構成するには、Popen のenvパラメーターを使用できます (例: env=dict(os.environ, ENVVAR='value').

Python で bash コマンドをエミュレートするsourceことは可能ですが、おそらくそれに依存する部分は bash-script に残す必要があります。

于 2015-09-23T17:54:13.027 に答える