subprocess Popen使用

介绍

相关的介绍在这篇博客里介绍的很好了:

http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html

这里介绍些自己的理解.


 

子进程函数

下面两个函数call, check_call是阻塞形式的调用, 即只有等子进程结束后才会进行后面的代码;

而Popen函数不是阻塞运行, 但只有等待子进程介绍后才会结束;

subprocess.call(cmd)
subprocess.check_call(cmd)
subprocess.Popen(cmd)

 

 处理子进程的函数如下,

wait是等待子进程介绍, 返回码为0则说明正常运行结束;

poll是查看子进程当前状态, 返回None则说明还在运行中;

另外两个就是终止, 杀死进程;

subprocess.wait()
subprocess.poll()
subprocess.terminate()
subprocess.kill()

 


 

Popen参数

Popen参数有很多, 参考上面的连接介绍的很好;

对于shell这个参数, 需要注意,

当shell=True的时候, 是在shell中运行, 此时 cmd 可以是字符串如下, 但如文档里说的, 该参数是存的安全隐患, 可能会被shell注入, 如 cmd = "; rm -rf /"; 

Warning:  Using shell=True can be a security hazard. See the warning under Frequently Used Arguments for details.

cmd = "tail -f text.txt"
Popen(cmd,shell=True)

所以建议是关闭shell, 此时可以如下处理:

cmd = "tail -f text.txt"
cmd = cmd.split()
Popen(cmd)

 


 

PIPE

  介绍下stdin与stdout, 这两个就是可以用来作为父进程与子进程之间通信用的, 如这里的管道PIPE, 也可以是文件 或None(直接在父进程里输出);

subprocess.PIPE功能非常强大, 但也存在一个问题, 就是如果子进程输出内容数据太多(大于65536字节), 会导致PIPE内存不足, 子进程被huang, 子进程永远无法结束, 

Note:   Do not use stdout=PIPE or stderr=PIPE with this function as that can deadlock based on the child process output volume. Use Popen with the communicate() method when you need pipes.

对于这个问题有不少人出现,并给出了相应的方法:

http://noops.me/?p=92

http://stackoverflow.com/questions/1180606/using-subprocess-popen-for-process-with-large-output

其建议有两个:

要么用文件代替stdout,

要么用communicate()及时读出文件的内容;   (对于这个处理好像不行, 文档里又这么说, 感觉说的前后矛盾

Note:  The data read is buffered in memory, so do not use this method if the data size is large or unlimited.

)

 

posted on 2016-04-28 16:44  He2Li  阅读(507)  评论(0编辑  收藏  举报