python subprocess popen 多次重定向_python subprocess.Popen系列问题

本文介绍了如何使用Python的subprocess.Popen处理命令执行超时问题,特别是涉及子进程及其孙进程的情况。文章通过实例展示了如何正确设置超时回调、关闭管道以及使用preexec_fn参数来确保子进程及其子进程组能在超时后被正确终止,避免阻塞问题。还讨论了使用`os.killpg`和`signal.SIGKILL`来结束进程组。最后提到了`timeout`命令与Python 2.7中`subprocess.Popen`结合使用的方法。
摘要由CSDN通过智能技术生成

最近在项目中遇到一个需求,前端发来一个命令,这个命令是去执行传递过来的一个脚本(shell 或者python),并返回脚本的标准输出和标准出错,如果执行超过设定时间还没结束就超时,然后终止脚本的执行。实现这个功能,自然而然先想到的是subprocess这个库了。

因此,在后端的一个脚本中调用python的subprocess去执行传递过来的脚本,通常情况下subprocess都能运行的很好,完成脚本的执行并返回。最初的实现代码如下:

run_cmd.py

#!/usr/bin/python

# -*- coding: utf-8 -*-

import subprocess

from threading import Timer

import os

class test(object):

def __init__(self):

self.stdout = []

self.stderr = []

self.timeout = 10

self.is_timeout = False

pass

def timeout_callback(self, p):

print 'exe time out call back'

print p.pid

try:

p.kill()

except Exception as error:

print error

def run(self):

cmd = ['bash', '/home/XXXX/test.sh']

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

my_timer = Timer(self.timeout, self.timeout_callback, [p])

my_timer.start()

try:

print "start to count timeout; timeout set to be %d \n" % (self.timeout,)

stdout, stderr = p.communicate()

exit_code = p.returncode

print exit_code

print type(stdout), type(stderr)

print stdout

print stderr

finally:

my_timer.cancel()

但是偶然间测试一个shell脚本,这个shell脚本中有一行ping www.baidu.com &,shell脚本如下:

test.sh

#!/bin/bash

ping www.baidu.com (&) #加不加&都没区别

echo $$

python(父进程)用subprocess.Popen新建一个进程(子进程)去开启一个shell, shell新开一个子进程(孙进程)去执行ping www.baidu.com的命令。由于孙进程ping www.baidu.com一直在执行,就类似于一个daemon程序,一直在运行。在超时时间后,父进程杀掉了shell子进程,但是父进程阻塞在了p.communicate函数了,是阻塞在了调用wait()函数之前,感兴趣的朋友可以看一下源码_communicate函数,linux系统重点看_communicate_with_poll和_communicate_with_select函数,你会发现是阻塞在了while循环里

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值