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应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数, ...
随机推荐
- PAT甲级——A1061 Dating
Sherlock Holmes received a note with some strange strings: Let's date! 3485djDkxh4hhGE 2984akDfkkkkg ...
- apt-get正在等待报头(waiting for headers)
可能的解决方法 1. 删除/var/cache/apt/archives/下的所有文件.可能是上次没有成功导致遗留了部分文件. 2. 如果使用的是代理,需要检查DNS.如果机器不能连接DNS服务器,要 ...
- 数据交换格式之 - Json
Json简介: JSON是JavaScript对象表示法,是一种与语言无关的数据交换的格式,是一种完全独立于语言的文本格式. 使用ajax进行前后台数据交换,移动端与服务端的数据交换. web客户端和 ...
- iOS CALayer之CAEmitterLayer粒子发射器的神奇效果
https://www.jianshu.com/p/c54ffd7412e7 想必以前QQ空间的点赞效果大家都知道吧,点赞之后按钮周围会有一圈爆裂的小圆点:还有微信的红包雨表情动画等,以及烟花,火焰效 ...
- Django项目:CRM(客户关系管理系统)--36--28PerfectCRM实现King_admin编辑限制
#admin.py # ————————01PerfectCRM基本配置ADMIN———————— from django.contrib import admin # Register your m ...
- BZOJ 4554: [Tjoi2016&Heoi2016]游戏
Time Limit: 20 Sec Memory Limit: 128 MB Submit: 951 Solved: 572 [Submit][Status][Discuss] Descriptio ...
- JS---案例:表格隔行变色(鼠标划过背景色恢复)
案例:表格隔行变色(鼠标划过背景色恢复) <!DOCTYPE html> <html> <head lang="en"> <meta ch ...
- spring cloud深入学习(二)-----服务注册中心spring cloud eureka
服务治理 主要用来实现各个微服务实例的自动化注册与发现,为啥需要这玩意呢?在一开始比如A系统调用B服务,可能通过手工维护B服务的实例,并且还得采用负载均衡等方式,这些全部都得需要手工维护,等后面系统越 ...
- nfs网络共享服务基础
nfs原理 1.开启RPC服务 2.NFS向RPC服务注册启动的端口 3.用户向RPC询问NFS服务的端口 4.RPC返回端口给客户端 5.客户端通过获得的端口与NFS服务器进行数据传输 实验步骤 一 ...
- mysql向某个字段前边追加一个字符串CONCAT命令
比如,我在处理图片的时候把https写成了tps 那我就要补全 UPDATE t_article set imgs=CONCAT('ht',imgs);