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.
)