2013-03-23 88 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()上下文中运行该命令。