subprocess.Popen()替换os.system()的问题

时间:2013-03-23 06:54:10

标签: python subprocess

我试图通过48核集群上的python脚本生成一组文件,这些集群实际上有一台主机和3台从机。我需要生成一组文件,在它们上运行一些脚本,收集结果然后删除它们。我再次重复进程 - 重新生成文件,执行,删除等, 当我删除并重新生成具有相同名称的文件时,我看到从机抱怨它无法找到文件。 我正在通过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

3 个答案:

答案 0 :(得分:2)

  

我无法得到像subprocess.Popen('cd /whatever_directory')这样简单的事情。

每个进程的当前工作目录独立于系统中的其他进程。

当你启动一个子进程(使用这些机制中的任何一种)并将它转到cd到另一个目录时,这对父进程没有影响,即在你的Python脚本上。

要更改脚本的当前工作目录,您应该使用os.chdir()

答案 1 :(得分: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
>>> 

但你可以绕过shell--这有助于解决安全问题 - 如果你的问题允许,可以将命令参数分解为列表:

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

请注意,这次输出是字符串$$,而不是进程ID,因为这次shell没有解释字符串。

例如,对于原始示例,您可以使用:

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

,如果path和/或module包含对shell特殊的字符,则可以避免出现问题。

(您甚至可能希望使用subprocess.Popen致电cwd = path并取消对os.path.join的调用,但这取决于其他事项。)

答案 2 :(得分:0)

我可能没有直接回答你的问题,但是对于需要运行子进程的任务,我总是使用plumbum

IMO,它使任务变得更加简单和直观,包括在远程机器上运行。

使用plumbum,为了设置子进程的工作目录,您可以在with local.cwd(path): my_cmd()上下文中运行该命令。

相关问题