[英]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.Popen
与cwd = 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.