python当中subprocess里call与Popen的用法区别

深入理解python中的subprocess模块 在实际开发过程中,我们经常会遇到需要从Python脚本中调用外部程序或脚本的场景。这时候,Python的subprocess模块就显得尤为重要。它是Python用来生成子进程、连接到它们的输入/输出/错误管道,以及获取它们的返回码的一个模块。本文将带你深入了解subprocess模块,学会如何高效地使用它来扩展你的Python脚本功能。subprocess模块是Python标准库的一部分,它为创建和管理子进程提供了强大的接口。在Python 2.4中引入以取代旧的模块(如os.system和。 阅读详情

http://blog.youkuaiyun.com/imzoer/article/details/8678029


subprocess的目的就是启动一个新的进程并且与之通信。

subprocess模块中只定义了一个类: Popen。可以使用Popen来创建进程,并与进程进行复杂的交互。它的构造函数如下:

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

参数args可以是字符串或者序列类型(如:list,元组),用于指定进程的可执行文件及其参数。如果是序列类型,第一个元素通常是可执行文件的路径。我们也可以显式的使用executeable参数来指定可执行文件的路径。

参数stdin, stdout, stderr分别表示程序的标准输入、输出、错误句柄。他们可以是PIPE,文件描述符或文件对象,也可以设置为None,表示从父进程继承。

如果参数shell设为true,程序将通过shell来执行。

参数env是字典类型,用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。

subprocess.PIPE

  在创建Popen对象时,subprocess.PIPE可以初始化stdin, stdout或stderr参数。表示与子进程通信的标准流。

subprocess.STDOUT

  创建Popen对象时,用于初始化stderr参数,表示将错误通过标准输出流输出。

Popen的方法:

Popen.poll()

  用于检查子进程是否已经结束。设置并返回returncode属性。

Popen.wait()

  等待子进程结束。设置并返回returncode属性。

Popen.communicate(input=None)

  与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。

Popen.send_signal(signal)

  向子进程发送信号。

Popen.terminate()

  停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。

Popen.kill()

  杀死子进程。

Popen.stdin,Popen.stdout ,Popen.stderr ,官方文档上这么说:

stdin, stdout and stderr specify the executed programs’ standard input, standard output and standard error file handles, respectively. Valid values are PIPE, an existing file descriptor (a positive integer), an existing file object, and None.

Popen.pid

  获取子进程的进程ID。

Popen.returncode

  获取进程的返回值。如果进程还没有结束,返回None。

---------------------------------------------------------------

简单的用法:

  1. p=subprocess.Popen("dir", shell=True)  
  2. p.wait()  
p=subprocess.Popen("dir", shell=True)
p.wait()

shell参数根据你要执行的命令的情况来决定,上面是dir命令,就一定要shell=True了,p.wait()可以得到命令的返回值。

如果上面写成a=p.wait(),a就是returncode。那么输出a的话,有可能就是0【表示执行成功】。

---------------------------------------------------------------------------

进程通讯

如果想得到进程的输出,管道是个很方便的方法,这样:

  1. p=subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
  2. (stdoutput,erroutput) = p.<span>commu</span>nicate()  
p=subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdoutput,erroutput) = p.communicate()

p.communicate会一直等到进程退出,并将标准输出和标准错误输出返回,这样就可以得到子进程的输出了。

再看一个communicate的例子。

上面的例子通过communicate给stdin发送数据,然后使用一个tuple接收命令的执行结果。

------------------------------------------------------------------------

上面,标准输出和标准错误输出是分开的,也可以合并起来,只需要将stderr参数设置为subprocess.STDOUT就可以了,这样子:

  1. p=subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)  
  2. (stdoutput,erroutput) = p.<span>commu</span>nicate()  
p=subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
(stdoutput,erroutput) = p.communicate()

如果你想一行行处理子进程的输出,也没有问题:

  1. p=subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)  
  2. while True:  
  3.     buff = p.stdout.readline()  
  4.     if buff == '' and p.poll() != None:  
  5.         break  
p=subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
    buff = p.stdout.readline()
    if buff == '' and p.poll() != None:
        break

------------------------------------------------------

死锁

但是如果你使用了管道,而又不去处理管道的输出,那么小心点,如果子进程输出数据过多,死锁就会发生了,比如下面的用法:

  1. p=subprocess.Popen("longprint", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)  
  2. p.wait()  
p=subprocess.Popen("longprint", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p.wait()

longprint是一个假想的有大量输出的进程,那么在我的xp, Python2.5的环境下,当输出达到4096时,死锁就发生了。当然,如果我们用p.stdout.readline或者p.communicate去清理输出,那么无论输出多少,死锁都是不会发生的。或者我们不使用管道,比如不做重定向,或者重定向到文件,也都是可以避免死锁的。

----------------------------------

subprocess还可以连接起来多个命令来执行。

在shell中我们知道,想要连接多个命令可以使用管道。

在subprocess中,可以使用上一个命令执行的输出结果作为下一次执行的输入。例子如下:

例子中,p2使用了第一次执行命令的结果p1的stdout作为输入数据,然后执行tail命令。

- -------------------

下面是一个更大的例子。用来ping一系列的ip地址,并输出是否这些地址的主机是alive的。代码参考了Python unixLinux 系统管理指南。

  1. #!/usr/bin/env python  
  2.   
  3. from threading import Thread  
  4. import subprocess  
  5. from Queue import Queue  
  6.   
  7. num_threads=3  
  8. ips=['127.0.0.1','116.56.148.187']  
  9. q=Queue()  
  10. def pingme(i,queue):  
  11.     while True:  
  12.         ip=queue.get()  
  13.         print 'Thread %s pinging %s' %(i,ip)  
  14.         ret=subprocess.call('ping -c 1 %s' % ip,shell=True,stdout=open('/dev/null','w'),stderr=subprocess.STDOUT)  
  15.         if ret==0:  
  16.             print '%s is alive!' %ip  
  17.         elif ret==1:  
  18.             print '%s is down...'%ip  
  19.         queue.task_done()  
  20.   
  21. #start num_threads threads  
  22. for i in range(num_threads):  
  23.     t=Thread(target=pingme,args=(i,q))  
  24.     t.setDaemon(True)  
  25.     t.start()  
  26.   
  27. for ip in ips:  
  28.     q.put(ip)  
  29. print 'main thread waiting...'  
  30. q.join();print 'Done'  
#!/usr/bin/env python

from threading import Thread
import subprocess
from Queue import Queue

num_threads=3
ips=['127.0.0.1','116.56.148.187']
q=Queue()
def pingme(i,queue):
	while True:
		ip=queue.get()
		print 'Thread %s pinging %s' %(i,ip)
		ret=subprocess.call('ping -c 1 %s' % ip,shell=True,stdout=open('/dev/null','w'),stderr=subprocess.STDOUT)
		if ret==0:
			print '%s is alive!' %ip
		elif ret==1:
			print '%s is down...'%ip
		queue.task_done()

#start num_threads threads
for i in range(num_threads):
	t=Thread(target=pingme,args=(i,q))
	t.setDaemon(True)
	t.start()

for ip in ips:
	q.put(ip)
print 'main thread waiting...'
q.join();print 'Done'

在上面代码中使用subprocess的主要好处是,使用多个线程来执行ping命令会节省大量时间。

假设说我们用一个线程来处理,那么每个 ping都要等待前一个结束之后再ping其他地址。那么如果有100个地址,一共需要的时间=100*平均时间。

如果使用多个线程,那么最长执行时间的线程就是整个程序运行的总时间。【时间比单个线程节省多了】

这里要注意一下Queue模块的学习。

pingme函数的执行是这样的:

启动的线程会去执行pingme函数。

pingme函数会检测队列中是否有元素。如果有的话,则取出并执行ping命令。

这个队列是多个线程共享的。所以这里我们不使用列表。【假设在这里我们使用列表,那么需要我们自己来进行同步控制。Queue本身已经通过信号量做了同步控制,节省了我们自己做同步控制的工作=。=】

代码中q的join函数是阻塞当前线程。下面是e文注释

 Queue.join()

  Blocks until all items in the queue have been gotten and processed(task_done()).

---------------------------------------------

学习Processing模块的时候,遇到了进程的join函数。进程的join函数意思说,等待进程运行结束。与这里的Queue的join有异曲同工之妙啊。processing模块学习的文章在这里

Python之subprocess模块 subprocess模块是Python中用于启动和管理子进程的一个强大工具,替代了旧有的os.system和os.spawn系列函数。通过这个模块,您可以从Python脚本中执行系统命令和其他可执行程序,并与之进行交互。在Python的subprocess模块中,有一些旧的API函数,比如call()、check_call()和check_output()。这些函数在Python 3.5及更早版本中被广泛使用。 阅读详情

相关推荐

Python 中 subprocess模块的使用

文章目录前言1、subprocess模块简介一、subprocess模块的遍历函数1、call函数(1)参数命令为数组时(2)参数命令为字符串时2、check_call函数3、check_output函数 前言 subprocess在jupyter notebook中被调用时与在python 中调用会有一些不一样的地方。 1、subprocess模块简介 subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。 这个模块用来创建和管理子进程。它提供了高层次.

刘石头的博客 7643

【Python】python之subprocess模块详解

【Python】python之subprocess模块详解 subprocess模块 subprocess是Python 2.4中新增的一个模块,它允许你生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码。这个模块的目的在于替换几个旧的模块和方法,如: os.system os.spawn* 1. subprocess模块中的常用函数 函数 描述 subprocess.run() Python 3.5中新增的函数。执行指定的命令,等待命令执行

qq_43331089的博客 7万+

3分钟接入满血版DeepSeek-R1:字节火山引擎手把手教程!免费50万tokens!

3分钟接入满血版DeepSeek-R1:字节火山引擎手把手教程!免费50万tokens!

hunteritself的博客 2万+

python中的subprocess.Popen()

python popen

老鹰不捉小鸡 8754

手把手教你用ESP32驱动MAX30102心率血氧传感器(含完整代码)

本文详细介绍了如何使用ESP32微控制器驱动MAX30102心率血氧传感器,构建智能健康监测系统。内容涵盖PPG原理、硬件连接、驱动配置、信号处理算法以及Web服务器数据可视化,提供完整代码实现,帮助开发者快速上手物联网健康设备开发。

weixin_29208077的博客 586

手把手教你用Sentinel-1和SNAP处理InSAR数据:从下载到生成沉降图(附Python脚本)

本文详细介绍了如何使用Sentinel-1数据和SNAP软件处理InSAR数据,从下载到生成地表沉降图的全流程。通过Python脚本实现自动化处理,适用于城市扩张和地质脆弱带的地表沉降监测,提供高性价比的毫米级形变监测方案。

weixin_26800111的博客 267

python中subprocess里call与popen的用法区别

subprocess的目的就是启动一个新的进程并且与之通信。 subprocess模块中只定义了一个类: Popen。可以使用Popen来创建进程,并与进程进行复杂的交互。它的构造函数如下: subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_...

banxieshi3876的博客 1278

开源大模型推理GPU资源评估以及优化

随着大模型的火热很多项目中都使用到了开源大模型,这时候准确评估大模型的GPU资源非常重要,主要有下面几个方面:GPU是昂贵的资源。高估内存需求可能导致在硬件上的不必要支出,而低估则可能导致系统故障或性能下降。:适当的内存管理确保模型高效运行,能够更快地响应用户并处理更多并发请求。:随着需求的增长,理解内存需求对于在不牺牲性能或产生高昂成本的情况下扩展服务至关重要。尽管其重要性显而易见,但计算用于服务大型语言模型(LLM)的GPU内存并不简单。

优快云DN的博客 3116

python popen和open_python中subprocess里call与popen的用法区别

subprocess的目的就是启动一个新的进程并且与之通信。subprocess模块中只定义了一个类: Popen。可以使用Popen来创建进程,并与进程进行复杂的交互。它的构造函数如下:subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, ...

weixin_39717598的博客 473

手机拍照背后的隐形功臣:一文读懂高通ISP三兄弟(IFE/BPS/IPE)如何协同工作

本文深入解析了高通ISP三兄弟(IFE/BPS/IPE)在手机拍照中的协同工作机制。通过拟人化比喻,详细介绍了IFE作为图像前端引擎的分流预处理、BPS作为RAW格式修图师的专业处理,以及IPE作为全能后期制作人的多面功能,揭示了三者在图像处理pipeline中的高效配合与技术创新。

weixin_27032989的博客 528

深度拆解 ‘High-Frequency Trading’ (HFT) 系统:解析如何在 100 纳秒内完成从网卡到 C++ 策略的响应

在100纳秒内完成从网卡到C++策略的响应,这是一项对技术栈每一个层面都进行极限优化的系统工程。它要求我们深入理解计算机体系结构、操作系统、网络协议和C++语言的底层机制。从物理距离的极致缩短,到高性能网卡和内核旁路技术,再到C++代码中每一个字节、每一个CPU周期的精打细算,HFT系统展现了人类对计算速度的永恒追求。这项技术不仅仅应用于金融交易,其背后的低延迟理念和实现方法,如DPDK、无锁编程、硬件加速等,正在逐渐渗透到其他对延迟敏感的领域,例如电信网络、边缘计算和工业自动化。

weixin_41455464的博客 1039

python中os.system、os.popen、subprocess.popen的区别

最近项目中需要在python中执行shell脚本,以下解释使用os.system、 os.popen和subprocess.popen的区别:1.os.system该函数返回命令执行结果的返回值,system()函数在执行过程中进行了以下三步操作: 1.fork一个子进程; 2.在子进程中调用exec函数去执行命令; 3.在父进程中调用wait(阻塞)去等待子进程结束。 对于fork失败,

啥也不是 6万+

基于深度学习的鸟类检测识别系统:YOLOv5 + YOLOv8 + YOLOv10 + UI界面 + 数据集

YOLOv5是当前目标检测领域非常流行的模型,具有良好的检测精度和实时推理速度。其网络结构相比前几代YOLO模型进行了优化,尤其是在检测精度和计算效率上有了显著提高。YOLOv5特点高效性:能够在较低的硬件环境下进行实时检测。易于部署和使用:YOLOv5提供了简单的API接口,方便开发者快速集成和使用。优异的精度:在多个数据集上测试,表现出色。本文详细介绍了基于YOLOv5、YOLOv8和YOLOv10的鸟类检测识别系统的设计与实现。

YOLO 1114

浅谈Python3中subprocess.Popen与os.popen的区别

之前遇到一个使用os.popen时想屏蔽控制台的stderr打印的问题,在研究这个问题的时候,对os.popen稍微打卡看了下,发现popen其实只是对subprocess.Popen的封装,先把源码粘出来: def popen(cmd, mode="r", buffering=-1): if not isinstance(cmd, str): raise TypeEr...

Ls4034的专栏 1万+

脑电信号处理实战 01 | 从 0 跑通第一个 EEG 分析:加载、滤波、频谱与“睁眼闭眼“

本文以 UCI 公开数据集"EEG Eye State"为例,从零走通脑电处理的完整流水线——数据加载、1–40 Hz 带通滤波、Welch 功率谱、频带功率、通道相关性与箱线图质控、睁闭眼对比和时频分析,并用 8 张科研风格图层层揭示这份数据中的伪迹与通道重复问题,说明"流程跑得通不等于结果可信,质量控制永远先行"。

qq_53529450的博客 115

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

[python]subprocess模块学习-call, checkall, check_output, Popen

在Python中,我们通过使用标准库中的subprocess模块来fork一个子进程,并运行一个外部的程序(类似于在linux中fork一个子进程,然后在子进程中exec另外一个程序)。 这一模块中提供了多种方法: 1. subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) 1.1 参数

yuchen1986的专栏 1万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Python 3 中 subprocess.Popen 与 os.popen 的区别

os.popenos.popen 是 Python 提供的一个用于启动外部进程并与其交互的函数。这个函数在 Python 2 中很常用,但在 Python 3 中已经被标记为过时。os.popen 主要用于启动一个进程并返回一个文件对象,通过该文件对象可以读取进程的标准输出或写入标准输入。• command:要执行的命令字符串。• mode:文件打开模式,‘r’ 表示读取(默认),‘w’ 表示写入。• buffering:缓冲策略,通常设置为默认值 -1 即可。

ahuyccc的博客 1534

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Python 中 subprocess.run 与 subprocess.Popen 解析

和并非互斥,而是互补。前者适合绝大多数日常任务,后者则为复杂场景提供必要控制力。理解它们的参数、行为差异及适用边界,是编写健壮、高效系统脚本的关键。默认使用;仅在确实需要流式处理或交互时,才退回到Popen;始终考虑安全性、可移植性和错误处理。通过合理选择和正确使用这两个接口,你可以在 Python 中高效、安全地集成任何外部命令或程序。

bill的博客 1274

subprocess.Popen()的用法

subprocess.Popen()的简单用法 subprocess 模块允许你生成新的进程,连接它们的输入、输出、错误管道,并且获取它们的返回码。 subprocess.Popen(args, shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE,stdout=subprocess.PIPE) args 被用作启动进程的参数. 可能是...

jianpeng的工程笔记 7559

【python】subprocess模块中的Popen与call的区别

1.subprocess.call(*popenargs, **kwargs)   运行命令。该函数将一直等待到子进程运行结束,并返回进程的returncode。如果子进程不需要进行交互,就可以使用该函数来创建。 2.subprocess.Popen subprocess模块中只定义了一个类: Popen。可以使用Popen来创建进程,并与进程进行复杂的交互。它的构造函数如下: s

zhuiqiuuuu的博客 6693

python中popen函数_Python执行外部命令(subprocess,call,Popen)

一、Python执行外部命令1、subprocess模块简介subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。这个模块用来创建和管理子进程。它提供了高层次的接口,用来替换os.system*()、 os.spawn*()、 os.popen*()、os,popen2.*()和commands.*等模块和函数。subprocess提供了一个名为Po...

weixin_39834767的博客 876

Python中 os.popen、os.system和subprocess.popen方法介绍

本文只是简单介绍了os.popen、os.system和subprocess.popen这三个方法,subprocess.popen还有更多的用法,它提供了对进程更细粒度的控制。subprocess.popen方法可以替代os.popen、os.system方法,subprocess.popen是他们的超集,如果只是简单的cmd命令调用可以直接使用os.popen和os.system,更复杂的控制可以选用subprocess.popen方法,按照自己实际情况进行选择。

测试开发小记 6416

python subprocess popen sterr_python subprocess模块 run Popen

python commands模块在python3.x被subprocess取代run: 开启一个进程 Python 3.5中新增的函数。执行指定的命令,等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。call()方法能便捷的调用一个程序,并得到执行的返回码。该方法是同步执行,需要等待命令执行完成,并且stdout不能指向PIPE,默认继承父进程的输出。 执行指定...

weixin_36287955的博客 470
上一篇: 关于如何通过apktool获取apk package name(包名)以及activity name
下一篇: Android自定义View生命周期
class_brick
博客等级 码龄12年 223粉丝 76原创
评论 15
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值