2013-03-23 33 views
0

我想通過一個實際上有一個主機和三個從機的48核心羣集上的python腳本生成一組文件。我需要生成一組文件,在其上運行一些腳本,收集結果然後刪除它們。我再次重複該過程 - 重新生成文件,執行,刪除等, 當我刪除並重新生成具有相同名稱的文件時,我發現從屬機器抱怨它找不到這些文件。 我通過os.system()Subprocess.Popen()替換os.system()的問題

運行Python腳本,我從this post得知這是更好地利用subprocess.Popen()而不是os.system因此,它實際上等待我的腳本來生成我的文件,與執行操作前。我可以使用os.system("pause")time.sleep(whatever)進行等待,但我想將我的os.systems轉換爲subprocess.popens或subprocess.calls,並且我卡在這裏。

我跑過python文檔並嘗試了subprocess.Popen('ls'),但我無法得到像subprocess.Popen('cd /whatever_directory')這樣簡單的工作。

這可能聽起來很愚蠢,但我該如何執行如cdsubprocess而不是os.system('cd')這樣的簡單命令?

然後,我真的想把下面的代碼轉換成子程序。我該怎麼做?

import os,optparse 
from optparse import OptionParser 

parser.add_option("-m", "--mod",dest='module', help='Enter the entity name') 
parser.add_option("-f", "--folder", dest="path",help="Enter the path") 

module=options.module 
path=options.path 

os.system('python %s/python_repeat_deckgen_remote.py -m %s' %(path,module)) 

我剛剛用subprocess.Popen替換了os.system。 但它給了我很多的抱怨:

File "/usr/lib64/python2.6/subprocess.py", line 633, in __init__ 
    errread, errwrite) 
    File "/usr/lib64/python2.6/subprocess.py", line 1139, in _execute_child 
    raise child_exception 
OSError: [Errno 2] No such file or directory 

回答

2

由於NPE已經注意到,新過程不會影響現有過程(這意味着os.system('cd /some/where')對當前過程也沒有影響)。不過,在這種情況下,我認爲你在跳過os.system調用一個shell來解釋你傳入的命令,而subprocess.Popen不這樣做默認爲。但你可以告訴它這樣做:

proc = subprocess.Popen(
    'python %s/python_repeat_deckgen_remote.py -m %s' % (path, module), 
    shell = True) 
status = proc.wait() 

如果你調用內置命令shell或使用shell擴展,有必要調用shell(假設你不願意來模擬它):

>>> import subprocess 
>>> x = subprocess.Popen('echo $$') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/subprocess.py", line 679, in __init__ 
    errread, errwrite) 
    File "/usr/local/lib/python2.7/subprocess.py", line 1249, in _execute_child 
    raise child_exception 
OSError: [Errno 2] No such file or directory 
>>> x = subprocess.Popen('echo $$', shell = True); x.wait() 
81628 
0 
>>> 

,但你可以繞過殼可與安全問題的幫助,如果您的問題許可證,通過破壞命令參數到一個列表:

>>> x = subprocess.Popen(['echo', '$$']); x.wait() 
$$ 
0 
>>> 

注意,這一次次這裏的e輸出是字符串$$,而不是進程ID,因爲這次shell沒有解釋字符串。

爲了您的原來的例子,例如,你可以使用:

proc = subprocess.Popen(['python', 
    os.path.join(path, 'python_repeat_deckgen_remote.py'), 
    '-m', 
    module]) 

避免了問題,如果path和/或module包含特殊的shell字符。

(你甚至可能要調用subprocess.Popencwd = path和消除呼叫os.path.join,雖然這取決於其他的東西。)

2

我不能夠得到一個簡單的事情,像subprocess.Popen('cd /whatever_directory')工作。

每個進程的當前工作目錄是獨立於系統中的其他進程的。

當您啓動一個子進程(使用這兩種機制之一)並將其獲取到cd到另一個目錄時,這對父進程(即Python腳本)沒有影響。

要更改腳本的當前工作目錄,應該使用os.chdir()

+0

我明白,我可以使用os.chdir()。但我的問題是,我想使用子進程而不是os.system運行命令。我使用的一個例子是:os.system('cd')起作用,其中'cd'是我所指的命令。那麼,在這種情況下,我如何用子進程替換os.system。 同樣,我已經使用os.system('python * .py)運行python命令。我想用子進程替換os.system,我該怎麼做? – Nanditha 2013-03-23 08:53:05

0

我可能沒有直接回答你的問題,但對於需要運行子進程的任務,我總是使用plumbum

IMO,它使任務更簡單,更直觀,包括在遠程機器上運行。

使用鉛筆,爲了設置子過程的工作目錄,您可以在with local.cwd(path): my_cmd()上下文中運行該命令。