1

我试图通过一个 48 核集群上的 python 脚本生成一组文件,该集群实际上有一个主机器和 3 个从机器。我需要生成一组文件,在它们上运行一些脚本,收集结果然后删除它们。我再次重复该过程-重新生成文件,执行,删除等,当我删除并重新生成具有相同名称的文件时,我看到从机抱怨它找不到文件。我正在运行python脚本os.system()

我从这篇文章中了解到,最好使用它subprocess.Popen()而不是os.system让它实际上等待我的脚本生成我的文件,然后再继续执行。我可以使用os.system("pause")ortime.sleep(whatever)等​​待,但我想将我的 os.systems 转换为 subprocess.popens 或 subprocess.calls 我被困在这里。

我浏览了 python 文档并尝试了subprocess.Popen('ls'),但我无法获得像subprocess.Popen('cd /whatever_directory')工作这样简单的东西。

听起来可能很傻,但是我如何执行这样一个简单的命令,比如cdthroughsubprocess而不是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
4

3 回答 3

2

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

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

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

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

于 2013-03-23T06:58:42.150 回答
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包含外壳特殊的字符,这可以避免问题。

(您甚至可能想调用subprocess.Popencwd = path消除对 的调用os.path.join,尽管这取决于其他事情。)

于 2013-03-23T09:47:09.093 回答
0

我可能不会直接回答您的问题,但是对于需要运行子流程的此类任务,我总是使用plumbum

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

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

于 2013-03-23T09:33:10.293 回答