2014-03-04 26 views
2

我試圖使用python自動化一個進程。如果我只是在終端工作流程看起來像:使用Python打開一個shell環境,運行一個命令並退出環境

user:> . /path/to/env1.sh 
user:> python something.py 
user:> exit 
user:> . /path/to/env2.sh 
user:> python something2.py 
user:> exit 

等等一些更多的步驟。每個env.sh都會生成一個新腳本,其中包含大量環境變量以及當前目錄中未設置的內容。我很確定我需要使用子進程,但我不確定如何去做。理想情況下,工作流程將執行:打開新shell - >運行一些命令 - >退出shell - >根據需要重複。

編輯:這似乎需要一些澄清。我知道如何使用subprocess.Popen()subprocess.call()從shell腳本中調用Python腳本的東西。這不是我需要的。當我們調用env.sh時,它設置了大量的環境變量和其他一些相關的東西,然後將你放入shell來運行命令。重要的是要注意,在運行所需命令之後,env.sh不會終止,直到一個類型爲exit。使用subprocess.call("./env.sh", shell = True)打開外殼並停在那裏。這就像輸入命令./env.sh,只是當發出exit命令時,其餘的python腳本。所以:

subprocess.call(". /path/to/env.sh", shell = True) 
subprocess.call("python something.py", shell = True) 

沒有做什麼,我需要它做的事,也沒有:

p = subprocess.Popen(". /path/to/env.sh", shell = True) 
subprocess.call("python something.py", shell = True) 
p.kill() 
+0

我的解決辦法使用Popen.communcate()我確實有一些麻煩讓我的輸入通過,但我在這裏找到答案: http://stackoverflow.com/questions/12965 023/python-subprocess-popen-communicate-equivalent-to-popen-stdout-read 需要從子進程中導入PIPE才能將字符串傳遞給子進程。我並不完全確定要選擇哪個答案,因爲他們中的任何一個都不是完全正確的,並且許多建議使用的模塊將被棄用。 – user3377586

+0

如果你認爲你知道答案,然後張貼*作爲答案*而不是評論,並接受它。 – jfs

回答

3

據我瞭解,你想運行一個命令,然後將它傳遞其他命令:

from subprocess import Popen, PIPE 

p = Popen("/path/to/env.sh", stdin=PIPE) # set environment, start new shell 
p.communicate("python something.py\nexit") # pass commands to the opened shell 
+0

但是,這並沒有和OP的代碼現在做的一樣。 '。無論「基本上需要什麼」並在當前環境中運行它,它都與「源」相同。你可以把它想成C的'#include'。 OP使用它來設置環境變量,以便在執行python程序時具有正確的環境。你的解決方案通過stdin將'python something.py \ nnext'(作爲字符串)傳遞給腳本 - 我不知道這是怎麼一回事...... – mgilson

+0

@mgilson:'source whatever' has ** no **對父母的影響。如果你的目的是改變環境變量,那麼調用'call(「source whatever,shell = True)是**毫無意義的**。 – jfs

+0

當然,它會影響父母。這就是你使用它的原因。這就是爲什麼在你改變一些東西之後你會做'source〜/ .bashrc'的原因。您可以在當前環境中選擇這些更改。 FWIW,我只做了一個簡單的測試,相當於:'echo「export FOO = Bar」> foo.sh; 。 foo.sh; echo $ {FOO}'和第二個'echo'工作。你想說這個改變不會傳播到Python嗎?我同意你的意見,但這不是問題。我們試圖在python中重現OP的* bash *代碼 - 而python有不同的機制來設置子進程中的環境(正如我已經指出的那樣)。 – mgilson

3

您可以使用subprocess

>>> import subprocess 
>>> subprocess.call('python something.py', shell = True) 

或者你可以使用os

>>> import os 
>>> os.system('python something.py') 

下面是一個例子(在揚聲器轉):

>>> import os 
>>> os.system('say Hello') 
+0

我很欣賞這個答案,但在我的問題中,我規定命令需要在由/path/to/env.sh打開的shell中運行,而不僅僅是我稱之爲初始python腳本的shell。 – user3377586

6

subprocess呼叫(特別Popen)接受一個env參數,它是environement變量到值的映射。你可以使用它。例如

env = {'FOO': 'Bar', 'HOME': '/path/to/home'} 
process = subprocess.Popen(['python', 'something.py'], env=env) 

當然,通常情況下,最好是隻需要調用一些功能後,*進口*荷蘭國際集團something.py,而不是產卵一個全新的過程。

+0

我並沒有最終使用env,但是您激勵我再次瀏覽文檔,並且徹底閱讀了Popen構造函數,並找到了我需要的東西。 – user3377586

+0

似乎所有OP想要的是[將命令傳遞到由'env.sh'啓動的shell](http://stackoverflow.com/a/22198788/4279) – jfs

0

這是您的help .... 對於運行命令你可以做:

1)

from subprocess import call 
call(["ls", "-l"]) 

2)

import os 
os.system("command") 

實施例:

import os 
f = os.popen('date') 
now = f.read() 
print "Today is ", now 

爲使終端可以imp的ORT os模塊:

import os 
os.system('python script.py') 

或者如前所述,您可以使用import subprocess

+0

我運行的命令需要在打開的shell中/path/to/env.sh不是調用父腳本的同一個shell。 – user3377586

+0

確定閱讀[鏈接](http://docs.python.org/2/library/subprocess.html#subprocess.Popen) – MLSC

+0

閱讀這些鏈接:[1](http://docs.python.org/2 /library/subprocess.html)[2](http://docs.python.org/2/tutorial/interpreter.html)[3](http://www.tutorialspoint.com/python/python_environment.htm) – MLSC

-2
p = subprocess.Popen(". /path/to/env.sh", shell = True, stdout=subprocess.PIPE).communicate() 
subprocess.call("python something.py", shell = True).communicate() 
+0

這是行不通的。第一條命令的想法是爲第二條命令設置環境。你在第一個命令中設置環境,但它不會傳播回python,所以當你執行第二個命令時,它仍然在python的相同環境中執行。 – mgilson

+0

-1:'call()'返回一個整數(退出代碼)。它沒有'.communicate()'方法。 – jfs

相關問題