繁体   English   中英

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

[英]Issues with subprocess.Popen() replacing os.system()

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

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

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

听起来可能很愚蠢,但是如何通过subprocess os.system('cd')而不是os.system('cd')执行诸如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

我无法像subprocess.Popen('cd /whatever_directory')这样简单的东西工作。

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

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

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

正如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 ,虽然依赖于其他的事情。)

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM