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

最近在项目中遇到一个需求,前端发来一个命令,这个命令是去执行传递过来的一个脚本(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循环里

你可能感兴趣的:(python,subprocess,popen,多次重定向)