subprocess库是一个十分强大且常用的库,它可以用来调用第三方工具(例如:exe、另一个python文件、命令行工具)。

1.常用函数
call() :执行由参数提供的命令,把数组作为参数运行命令。

retcode = subprocess.call(["ls", "-l"])
【注意1】 在Linux系统中上述代码运行没有问题,但是在windows中上述代码运行会报错:FileNotFoundError: [WinError 2] 系统找不到指定的文件。这是由于call函数的shell参数默认为False状态,这个状态windows下并不支持,需要修改shell为True状态:

retcode = subprocess.call("ls -l",shell=True)
【注意2】 call函数建议在Linux系统中使用,在Windows系统中有诸多限制。在Linux系统中,call函数会直接打印出参数运行后的结果,而赋值的是返回结果,而非运行结果。例如下面的运行结果,直接打印出目录,但r的值为0。

【注意3】 在Windows系统下使用call函数要注意命令的区别,例如:复制应该是“copy”而非“cp”。
错误代码:

subprocess.call(['cp', train_blur[index], os.path.join(args.output_path, 'train\\blur\\%s'%('_'.join(train_blur[index].split('\\')[-3:])))], shell=True)
正确代码:

subprocess.call(['copy', train_blur[index], os.path.join(args.output_path, 'train\\blur\\%s'%('_'.join(train_blur[index].split('\\')[-3:])))], shell=True)
【注意4】 在使用call函数的时候尽量不要使用shell的True参数,会造成安全上的问题。

※运行代码:

retcode = subprocess.call(["ls", "-l"])

check_call():和上面的call()作用相同,唯一的不同点在于对于返回值的处理上。
当call()函数和check_call()函数的返回值都为1的时候:

check_call()函数的返回值为1的时候会报错。并且check_call()函数会把运行结果赋值给变量,而call()函数会把返回值复制给变量。

check_output():和上面的两个函数作用相同,唯一的不同点是,这个函数可以获得返回的结果。

2. Popen模块
Popen():相较于上面的三个函数,popen()更加精细化,上面的三个函数都是父进程会等待子进程结束,但是popen()函数只有在使用 wait() 时才会等待。所以,上面的三个函数相当于,popen+wait的组合。

child = subprocess.Popen(['ping','-c','4','127.0.0.1'])
child.wait(4)
#或
child = subprocess.Popen('ping -c4 127.0.0.1',shell=True)
child.wait(4)
wait()还可以设置超时时间,超过时间父进程将就不在等待了。
结果如图:
Popen还有三个参数,分别为:stdin、stdout、stderr。
例如:

p2 = subprocess.Popen(["grep","0:0"],stdin=p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout是标准输出重定向;
stdin:我们可以看到,结果被储存进了subprocess.PIPE里,实际上,subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe),我们也可以利用这个特性,将stdout和stdin一起使用进行连续的输入输出:

c1 = subprocess.Popen(["uname","-a"], stdout=subprocess.PIPE)
c2 = subprocess.Popen(["wc"],stdin=child1.stdout,stdout=subprocess.PIPE)
out = c1.communicate()
print(out)
out = c2.communicate()
print(out)

subprocess.PIPE实际上为文本流提供一个缓存区。c1的stdout将文本输出到缓存区,随后c2的stdin从该PIPE中将文本读取走。c2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
stderr:不常用,返回错误信息,我们可一对其进行标准输出,例如:

p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
【注意1】 communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。

communicate() 返回一个元组 (stdout_data, stderr_data) 。如果流以文本模式打开,则数据将是字符串;否则,字节。

请注意,如果要将数据发送到进程的标准输入,则需要使用 stdin=PIPE 创建 Popen 对象。同样,要在结果元组中获得除 None 以外的任何内容,您还需要提供 stdout=PIPE 和/            或 stderr=PIPE

如果进程在 timeout 秒后没有终止,则会引发 TimeoutExpired 异常。捕获此异常并重试通信不会丢失任何输出。

如果超时到期,子进程不会被杀死,因此为了正确清理well-behaved应用程序应该杀死子进程并完成通信:

【注意2】 pipe的有大小限制,Linux默认的pipe size是64KB。当大于64kb时,如果使用 Popen.wait() 方式等待程序结束获取返回值,会导致死锁,程序卡在 wait() 调用上。communicate将数据不是放在pipe中,而是放在内存中
所以,推荐使用communicate方式获得返回结果
【注意3】 输出输入小技巧:当参数传入不进去的时候,例如ip地址,可以将参数拼接在一起传入,例如(注意“ip”前面的加号+):

p=subprocess.Popen("ping -c 4 " + ip, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

3. 子进程常用方法
child.pid:返回子进程的pid

child.poll() :检查子进程状态

child.kill() :终止子进程

child.send_signal() :向子进程发送信号

child.terminate() :终止子进程

Python subProcess库以及Popen类的使用的更多相关文章

  1. Python - 标准库部分函数、类的大致实现(持续更新)

    all() def all(iterable): for element in iterbale: if not element: return False return True any() def ...

  2. Python标准库06 子进程 (subprocess包)

    这里的内容以Linux进程基础和Linux文本流为基础.subprocess包主要功能是执行外部的命令和程序.比如说,我需要使用wget下载文件.我在Python中调用wget程序.从这个意义上来说, ...

  3. Python标准库---子进程 (subprocess包)

    这里的内容以Linux进程基础和Linux文本流为基础.subprocess包主要功能是执行外部的命令和程序.比如说,我需要使用wget下载文件.我在Python中调用wget程序.从这个意义上来说, ...

  4. Python标准库之subprocess模块

    运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python中,我们通过标准库中的subprocess ...

  5. Python多进程库multiprocessing中进程池Pool类的使用[转]

    from:http://blog.csdn.net/jinping_shi/article/details/52433867 Python多进程库multiprocessing中进程池Pool类的使用 ...

  6. Python subprocess.Popen communicate() 和wait()使用上的区别

    之所以会纠结到这个问题上是因为发现在调用Popen的wait方法之后程序一直没有返回.google发现wait是有可能产生死锁的.为了把这个问题彻底弄清楚,搜索一些资料过来看看: 原文链接:http: ...

  7. Python标准库——collections模块的Counter类

    1.collections模块 collections模块自Python 2.4版本开始被引入,包含了dict.set.list.tuple以外的一些特殊的容器类型,分别是: OrderedDict类 ...

  8. Python subprocess.Popen中communicate()和wait()区别

    刚开始我是使用的wait(),但是当adb命令返回太多时,程序就会卡死,查询得知原因后,才使用了communicate(),communicate()返回一个元组:(stdoutdata, stder ...

  9. python subprocess popen 静默模式(不弹出console控制台)

    python subprocess popen 静默模式(不弹出console控制台) import subprocess,sys IS_WIN32 = 'win32' in str(sys.plat ...

  10. python - 标准库:subprocess模块

    subprocess的目的就是启动一个新的进程并且与之通信. subprocess模块中只定义了一个类: Popen. subprocess.Popen(args, bufsize=0, execut ...

随机推荐

  1. RSA趣题篇(简单型)

    1.n与p的关系 题目 ('n=', 288990088827100766680640490138486855101396196362885475612662192799072729620922966 ...

  2. phpcms - 在删除文章后实现自动删除tag标签

    在使用phpcms程序制作网站的时候,我们会发现文章模型新建一篇文章后会自动向数据库中插入关键词,但如果删除文章后,数据库中的关键词表中字段中还存在之前文章的关键词,那么怎样才能在phpcms后台中删 ...

  3. Kubernerts - 概览

    1. Kubernerts K8s,是用于自动部署.扩容和管理容器化应用程序的开源系统 1.1 特性 自动化上线与回滚 分步骤针对应用或者配置更改上线,监控应用的运行状态同时不会终止所有实例,若出现问 ...

  4. [转帖]AES算法(四)基本工作模式

    https://zhuanlan.zhihu.com/p/376077687 8 人赞同了该文章 本文所述工作模式可适用于 DES.AES 等分组密码算法中 分组密码算法只能加密固定长度为 N 比特的 ...

  5. [转帖]查看mysql分区名和各分区数据量

    – 查看mysql分区名和各分区数据量 SELECT table_name, partition_name, table_rows FROM information_schema.PARTITIONS ...

  6. [转帖]一个Linux 内核 bug 导致的 TCP连接卡死

    https://plantegg.github.io/2022/10/10/Linux%20BUG%E5%86%85%E6%A0%B8%E5%AF%BC%E8%87%B4%E7%9A%84%20TCP ...

  7. linux线程调度策略

    linux线程调度策略 这是一篇非常好的关于线程调度的资料,翻译自shed 目录 linux线程调度策略 Scheduling policies SCHED_FIFO: First in-first ...

  8. js引起的 xxxx of null

    在 vue 中操作 dom 元素的时候,报错 style of null 这个报错的原因,跟你代码的健壮性有关了; 这样就不会报错了 if( document.querySelectorAll(&qu ...

  9. 超级好用的elementui动态循环菜单

    <template> <div> <el-menu @select="selectMenu" :default-active="curren ...

  10. JS 逆向之 Hook,吃着火锅唱着歌,突然就被麻匪劫了!

    关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 什么是 Hook? Hook 中文译为钩子,Hook 实际上是 Windows 中提供的一种用以 ...