这是运行任意命令返回其stdout数据的Python代码,或者在非零退出代码上引发异常:
proc = subprocess.Popen(
cmd,
stderr=subprocess.STDOUT, # Merge stdout and stderr
stdout=subprocess.PIPE,
shell=True)
Run Code Online (Sandbox Code Playgroud)
communicate 用于等待进程退出:
stdoutdata, stderrdata = proc.communicate()
Run Code Online (Sandbox Code Playgroud)
该subprocess模块不支持超时 - 能够终止运行超过X秒的进程 - 因此,communicate可能需要永久运行.
在旨在在Windows和Linux上运行的Python程序中实现超时的最简单方法是什么?
我之间是完全糊涂了subprocess.call(),subprocess.Popen(),subprocess.check_call().
哪个是封锁哪个不是?
如果我用我的意思说的是subprocess.Popen()父进程是否等待子进程return/ exit它继续执行之前.
shell=True这些电话怎么影响?
有没有办法确保所有创建的子进程在Python程序的退出时间都死了?通过子进程,我指的是使用subprocess.Popen()创建的.
如果没有,我应该迭代所有发出的杀戮然后杀死-9?什么更干净?
当我使用子进程模块从另一个python脚本中启动python脚本时,子进程"完成"时会创建一个僵尸进程.除非我杀死我的父python进程,否则我无法终止此子进程.
有没有办法杀死子进程而不杀死父进程?我知道我可以通过使用wait()来实现这一点,但我需要使用no_wait()运行我的脚本.
这是我的想法:
首先,我使用subprocess.Popen创建了一个进程
第二,经过一段时间后,我试图通过Popen.kill杀死它()
import subprocess
import os, signal
import time
proc1 = subprocess.Popen("kvm -hda /path/xp.img", shell = True)
time.sleep(2.0)
print 'proc1 = ', proc1.pid
subprocess.Popen.kill(proc1)
Run Code Online (Sandbox Code Playgroud)
但是,"proc1"仍然存在于Popen.kill()之后.任何专家都可以告诉我如何解决这个问题吗?我很感激你的考虑.
感谢所有专家的评论,我做了你所做的一切,但结果仍然保持不变.
proc1.kill() #it sill cannot kill the proc1
os.kill(proc1.pid, signal.SIGKILL) # either cannot kill the proc1
Run Code Online (Sandbox Code Playgroud)
谢谢你们.
我仍然在等待你解决这个微妙问题的宝贵经验.
子进程以#开头
subprocess.Popen(arg)
Run Code Online (Sandbox Code Playgroud)
如果父母异常终止,有没有办法确保它被杀死?我需要这个在Windows和Linux上都可以工作.我知道这个Linux解决方案.
编辑:
subprocess.Popen(arg)如果使用不同的启动流程的方法存在解决方案,则可以放宽启动子流程的要求.
我正在使用python 2.5上的子进程模块生成一个java程序(准确地说是selenium服务器),如下所示:
import os
import subprocess
display = 0
log_file_path = "/tmp/selenium_log.txt"
selenium_port = 4455
selenium_folder_path = "/wherever/selenium/lies"
env = os.environ
env["DISPLAY"] = ":%d.0" % display
command = ["java",
"-server",
"-jar",
'selenium-server.jar',
"-port %d" % selenium_port]
log = open(log_file_path, 'a')
comm = ' '.join(command)
selenium_server_process = subprocess.Popen(comm,
cwd=selenium_folder_path,
stdout=log,
stderr=log,
env=env,
shell=True)
Run Code Online (Sandbox Code Playgroud)
一旦自动化测试完成,该过程应该被杀死.我正在使用os.kill这个:
os.killpg(selenium_server_process.pid, signal.SIGTERM)
selenium_server_process.wait()
Run Code Online (Sandbox Code Playgroud)
这不起作用.原因是shell子进程为java生成了另一个进程,并且我的python代码不知道该进程的pid.我已经尝试过杀死进程组os.killpg,但是这也会杀死运行此代码的python进程.由于其他原因,将shell设置为false,从而避免java在shell环境中运行也是不可能的.
如何杀死shell以及由它生成的任何其他进程?
当subprocess.Popen()我使用线程让我们同时运行它们从我的python脚本生成同一个应用程序的几个实例时,我遇到了一些问题.在每个线程中,我使用popen()调用运行应用程序,然后我等待它通过调用完成wait().问题似乎是wait()-call实际上并不等待进程完成.我只使用一个线程进行实验,并在进程启动时和完成时打印出文本消息.所以线程函数看起来像这样:
def worker():
while True:
job = q.get() # q is a global Queue of jobs
print('Starting process %d' % job['id'])
proc = subprocess.Popen(job['cmd'], shell=True)
proc.wait()
print('Finished process %d' % job['id'])
job.task_done()
Run Code Online (Sandbox Code Playgroud)
但即使我只使用一个线程,它也会在出现任何"完成进程..."消息之前打印出几个"正在启动进程..."消息.有wait()没有实际上没有等待的情况?我有几个不同的外部应用程序(C++控制台应用程序),它们将同时运行多个实例,对于其中一些我的代码可以工作,但对于其他实例,它不会.外部应用程序是否存在某些问题会以某种方式影响调用wait()?创建线程的代码如下所示:
for i in range(1):
t = Thread(target=worker)
t.daemon = True
t.start()
q.join() # Wait for the queue to empty
Run Code Online (Sandbox Code Playgroud)
更新1:我还应该补充一点,对于某些外部应用程序,我有时会得到proc.returncode-1073471801 的返回码().例如,其中一个外部应用程序将给出前两次Popen调用的返回代码,但不是后两个(当我有四个作业时).
更新2:为了清理,现在我在队列中有四个作业,这是四个不同的测试用例.当我运行我的代码时,对于其中一个外部应用程序,前两个 - Popen调用生成返回代码-1073471801.但是如果我打印出Popen调用的确切命令,并在命令窗口中运行它,它会毫无问题地执行.
解决了! 我设法解决了我遇到的问题.我认为问题在于我缺乏线程编程的经验.我错过了这样一个事实:当我创建了我的第一个工作线程时,他们会一直活着直到python脚本退出.错误的是,每次我将新项目放入队列时,我都会创建更多的工作线程(我会为每个要运行的外部程序批量执行此操作).所以当我进入第四个外部应用程序时,我有四个线程同时运行,即使我只认为我有一个.
我在Windows 8/XP上使用Python 2.7.
我有一个程序A使用以下代码运行另一个程序B:
p = Popen(["B"], stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
return
Run Code Online (Sandbox Code Playgroud)
B运行批处理脚本C. C是一个长时间运行的脚本,我希望B退出,即使C还没有完成.我使用以下代码完成了它(在B中):
p = Popen(["C"])
return
Run Code Online (Sandbox Code Playgroud)
当我运行B时,它按预期工作.然而,当我运行A时,我预计它会在B退出时退出.但是A等到C退出,即使B已经退出了.关于发生了什么以及可能的解决方案的任何想法?
不幸的是,将A改为看起来像B的明显解决方案不是一种选择.
以下是用于说明此问题的功能示例代码:https: //www.dropbox.com/s/cbplwjpmydogvu2/popen.zip?dl = 1
任何输入都非常感谢.
我想在子进程上使用超时
from subprocess32 import check_output
output = check_output("sleep 30", shell=True, timeout=1)
Run Code Online (Sandbox Code Playgroud)
不幸的是,虽然这会引发超时错误,但它会在30秒后发生.似乎check_output不能中断shell命令.
我可以在Python端做些什么来阻止它?我怀疑subprocess32无法终止超时进程.
python ×10
subprocess ×9
popen ×3
kill ×2
linux ×1
python-2.7 ×1
python-3.x ×1
timeout ×1
unix ×1
windows ×1