Python2.7下,调用subprocess启动子进程,读取子进程标准输出若干问题
1:如果调用的子进程也是一个python脚本,则subprocess.Popen中的bufsize=1无效果。也就是说,即使设置了bufsize=1表示进行行缓冲,子进程如果不显示调用sys.stdout.flush,父进程依然会阻塞在readline上:
#testbuf.py
import subprocess cmd = "./testsub.sh"
cmd2 = ["python", "testsub.py"]
sp = subprocess.Popen(cmd2, bufsize = 1, stdout = subprocess.PIPE) while True:
line = sp.stdout.readline()
print 'read line is ', line
if not line: break
testsub.py代码如下:
import time
import sys for i in range(100000):
print 'hello, world', i
#sys.stdout.flush()
time.sleep(1)
执行testbuf.py脚本,该脚本将会阻塞在sp.stdout.readline()上,除非将子进程testsub杀掉,否则,该脚本将会长时间阻塞在这条语句上。
如果将testsub.py中的sys.stdout.flush()前注释去掉,则父进程可以得到正常的输出。
如果执行的是shell脚本testsub.sh,则没有这种问题,该脚本代码如下:
#!/bin/bash for((i=;i<=;i++));
do
echo “hello, world”, $i
sleep
done
2:如果子进程是一个长时间运行的程序,而父进程想以行为单位实时读取子进程的输出,则父进程不能以for line in sp.stdout的形式读取子进程输出:
#testbuf.py import subprocess cmd = "./testsub.sh"
cmd2 = ["python", "testsub.py"]
sp = subprocess.Popen(cmd2, bufsize = , stdout = subprocess.PIPE) for line in sp.stdout:
print 'read line is ', line
if not line: break
这种情况下,进程阻塞在for line in sp.stdout上。这实际上是python2的一个bug:
https://bugs.python.org/issue3907
https://stackoverflow.com/questions/2804543/read-subprocess-stdout-line-by-line
https://ubuntuforums.org/showthread.php?t=916518
这个bug在python3中据说解决了,但是在python2下,还是不可以用for line in sp.stdout这种形式。可以使用readline:
for line in iter(proc.stdout.readline,''):
print line
3:如果子进程有大量输出,而父进程调用subprocess.Popen时又设置了stdout = subprocess.PIPE,并且没有及时读取stdout中的内容,则一旦缓冲区满了(缓冲区默认大小为65535),则子进程会在写入标准输出时hang住。
Python2.7下,调用subprocess启动子进程,读取子进程标准输出若干问题的更多相关文章
- Python下调用Linux的Shell命令
有时候难免需要直接调用Shell命令来完成一些比较简单的操作,比如mount一个文件系统之类的.那么我们使用Python如何调用Linux的Shell命令?下面来介绍几种常用的方法: 1. os 模块 ...
- 用 set follow-fork-mode child即可。这是一个 gdb 命令,其目的是告诉 gdb 在目标应用调用fork之后接着调试子进程而不是父进程,因为在 Linux 中fork系统调用成功会返回两次,一次在父进程,一次在子进程
GDB的那些奇淫技巧 evilpan 收录于 Security 2020-09-13 约 5433 字 预计阅读 11 分钟 709 次阅读 gdb也用了好几年了,虽然称不上骨灰级玩家,但 ...
- shell启动时读取的配置文件
bash shell具体可以分为3种类型,这3种类型为: 1 login shell 就是需要输入用户名和密码才能登陆的shell 2 可交互的非login shell 就是不用登陆的,但是可以同用户 ...
- windows下调用外部exe程序 SHELLEXECUTEINFO
本文主要介绍两种在windows下调用外部exe程序的方法: 1.使用SHELLEXECUTEINFO 和 ShellExecuteEx SHELLEXECUTEINFO 结构体的定义如下: type ...
- EventBus代替Intent将复杂对象传递给下一个即将启动的Activity
我觉得EventBus确实非常好,把我们从序列化中解脱出来,即使不序列化也能在界面间传递数据,但是有个前提,那是两个界面都已经存在并且注册了EventBus.而即将启动的下一个Activity就非常尴 ...
- linux 下mysql的启动 、调试、排错
Linux 下 MySQL 启动与关闭 说明 一.启动 1.1 MySQL 进程 可以用ps 命令查看进程: [root@rac2 ~]# ps -ef|grep mysql root 21 ...
- CentOS6.5_python2.7.3下virt-manager无法启动
配置virt-manager: 1.安装virt-manager, libvirt, qemu-kvm 2.配置libvirtd开机启动: chkconfig libvirtd on #取消开机启 ...
- myeclipse配置下tomcat debug启动很无比慢
myeclipse配置下tomcat debug启动很无比慢,而run启动很快今天照常使用MyEclipse 6.5 Blue Edition进行开发,但是却遇到一个怪问题.在MyEclipse环境下 ...
- memcached 在windows下安装及启动
memcached 在windows下安装及启动 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数, ...
随机推荐
- DLL编程总结
进行DLL的编程主要涉及到两个方面的问题,一个是要保证DLL中要导出的函数名不被编译器不可控地更改(在C++中由于重载机制的存在,会造成程序被编译时函数名被改变),其实就是要保证DLL导出的函数名与使 ...
- Python学习之列表--自动超市购物车
效果图: 实现代码: menu = [0,5000,500,9000,3000,30,50,7000,70,40]name = [0,"iphone","bicycle& ...
- python collections 模块 之namedtuple
namedtuple collections.namedtuple(typename, filed_name, *, rename=False, module=None) 创建一个以 typename ...
- Google 和 微软,就不是一个重量级的
看微软的 WinCE 模拟器,做得带模带样 Google 也不是新来的,但是 Android 模拟器,配置一下都那么费事 这就是差距,Google 比 微软 差了好几级
- 洛谷 3959 宝藏——枚举+状压dp
题目:https://www.luogu.org/problemnew/show/P3959 原来写了个不枚举起点的状压dp. #include<iostream> #include< ...
- 移植thinkPHP的dump()函数
由于公司的开发机没有开xdebug拓展,导致var_dump()在浏览器上看很不方便. 因此,加入从thinkphp搬过来的dump()函数. function dump($var, $echo=tr ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---装饰模式之StarBuzzCoffee[转]
1 2{<HeadFirst设计模式>之装饰模式 } 3{ 本单元中的类为被装饰者 } 4{ 编译工具: Delphi7.0 } 5{ E-Ma ...
- java知识点---文件分隔符
本篇讲述java编程中,怎样解决跨平台时,因不同系统中分隔符不同导致的文件或路径找不到的问题 首先来看两个例子: 一.linux系统和windows系统中的文件路径: Linux系统: Windows ...
- CSS 定位 (Positioning)
CSS 定位 (Positioning) 属性允许你对元素进行定位. CSS 定位和浮动 CSS 为定位和浮动提供了一些属性,利用这些属性,可以建立列式布局,将布局的一部分与另一部分重叠,还可以完成多 ...
- 基础篇-1.4Java流程语句的基础
1 条件语句 条件语句,即类似 if...else... 的语句,一个if语句包含了一个布尔表达式,以及一个或多个语句. if语句语法 if(布尔表达式) { // 布尔表达式为true时执行的语句块 ...