Python subprocess的使用

前言

部门内部存在大量代码使用Python去调用Shell或者JS脚本,因此重度依赖subprocess(使用Google的subprocess32),在使用subprocess的时候存在一些疑问。包括为什么 使用shell=TruePopen类如何使用等等。希望通过本篇文章,让自己掌握subprocess的使用。

使用

subprocess用于创建子进程去运行我们指定的可执行程序(文件、脚本)。核心是用Popen类。

常用的函数

(1)执行命令的函数

Python2

函数名 函数签名 check_call subprocess.check_call(args, , stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, other_popen_kwargs) check_output subprocess.check_output(args, , stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=None, timeout=None, text=None, **other_popen_kwargs)

check_call用于调用命令,会抛CalledProcessError。check_output会返回stdout,如果要把stderr也重定向到stdout,可以指定参数stderr=subprocess.STDOUT。两个函数的签名和Popen的构造函数参数类似。

Python3

函数名 函数签名 run subprocess.run(args, , stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, *other_popen_kwargs)

(2)Popen

以上的函数调用都是同步的,我们只能等待命令执行结束才能执行其他任务。想要异步的去运行一些比较耗时的命令可以使用更加强大的Popen类。

构造函数

构造函数签名 class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)

参数很多,常用的参数包括

args: 该参数可以是一个列表或者一个字符串。当传递一个列表时,列表的首元素应该是要执行的脚本或者可执行程序,其他元素是可执行程序的参数。

​ 如果传递的是字符串,则建议设置Shell=True。否则只能执行字符串为不带参数的可执行程序(Popen(“pwd”))。

shell=True: 如果希望直接使用shell去执行命令,可以指定shell=True。指定shell=True等同于 Popen([‘/bin/sh’, ‘-c’, args[0], args[1], …])。

常用方法

函数名 函数签名 poll Popen.poll() communicate Popen.communicate(input=None, timeout=None) wait Popen.wait(timeout=None)

poll: 检查子进程是否结束,子进程结束则返回 returncode属性,否则返回None

wait: 等待子进程结束

communicate: 读取子进程的stdout和stderr,向stdin写入。函数返回一个元组(stdout_data, stderr_data)。

实例:

#!/usr/bin/env python
coding=utf-8

from subprocess import Popen, TimeoutExpired, PIPE
from shlex import split

def count_lines(text):
"""
    count how much line in text
"""
    proc = Popen(split("wc -l"), stdout=PIPE, stdin=PIPE)
    print(bytes(text, encoding="utf-8"))
    #向子进程的标准输入写入数据,使用flush冲刷缓冲区
    proc.stdin.write(bytes(text, encoding="utf-8"))
    proc.stdin.flush()
    return proc

procs = []
for i in range(5):
    procs.append(count_lines("abcefcdnfsdf\n"))

for proc in procs:
    #从子进程的标准输入读取
    stdout, stderr = proc.communicate()
    print(str(stdout), stderr)

执行结果:

Python subprocess的使用

Original: https://www.cnblogs.com/dennis-wong/p/15811860.html
Author: 成蹊0xc000
Title: Python subprocess的使用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/582776/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Flask 易错点

    1.With上下文管理器 常用: with open("file_name","wb") as f: f.write("hello…

    Linux 2023年6月8日
    087
  • Mybatis的递归查询实现二级评论

    最近闲来无事,在做毕业设计。前台页面需要一个评论功能,感觉三方的评论太复杂,功能也太多。就想着自己写一个简单点的,本人比较菜,方法比较笨,可能效率不高。 环境介绍 后端:Sprin…

    Linux 2023年6月8日
    0107
  • kali使用clash for linux 代理

    404. 抱歉,您访问的资源不存在。 可能是URL不正确,或者对应的内容已经被删除,或者处于隐私状态。 [En] It may be that the URL is incorre…

    Linux 2023年5月27日
    0101
  • termius好用的shell终端

    ipad下可用 posted @2022-07-23 12:41 jiftle 阅读(75 ) 评论() 编辑 Original: https://www.cnblogs.com/…

    Linux 2023年5月28日
    0115
  • SpringBoot——自定义Redis缓存Cache

    SpringBoot自带Cache存在问题: 1.生成Key过于简单,容易冲突 默认为cacheNames + ":" + Key2.无法设置过期时间,默认时间…

    Linux 2023年5月28日
    0102
  • shell内置命令和外部命令的区别

    shell内置命令和外部命令的区别 内部命令实际上是shell程序的一部分,其中包含的是一些比较简单的linux系统命令,这些命令由shell程序识别并在shell程序内部完成运行…

    Linux 2023年6月7日
    083
  • Redis 分布式锁的实现

    0X00 测试环境 CentOS 6.6 + Redis 3.2.10 + PHP 7.0.7(+ phpredis 4.1.0) [root@localhost ~]# cat …

    Linux 2023年5月28日
    0110
  • 分布式锁

    非分布式下使用锁 利用版本号来检测数据是否发生变化,从而判断是否能进行更新 JAVA 使用比较交换机制-CAS(Compare And Swap)机制实现 i++非线程安全,使用原…

    Linux 2023年6月7日
    095
  • Git 不识别文件名字母大小写变化

    问题 今天为一个项目撰写持续构建计划,撰写 Jenkinsfile 之后进行构建时报错: [2022-05-23 16:54:21] unable to prepare conte…

    Linux 2023年6月7日
    0103
  • centos 7 安装zabbix 4.0

    一、zabbix简介 1、简介 zabbix([`zæbiks])是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix能监视各种网络参数如:…

    Linux 2023年6月7日
    0122
  • shell 变量的默认值

    在 shell 脚本中,如果要使用某个变量又想给它设置默认值,可以用 XX=${YY-ZZ} 的方式,其中 ZZ 会是 YY 没有设置时的默认值 另一种用法是 XX=${YY:-Z…

    Linux 2023年5月28日
    0107
  • 剑指offer计划21( 位运算简单)—java

    1.1、题目1 剑指 Offer 15. 二进制中1的个数 1.2、解法 通过判断每一位的与来识别1的数量。 1.3、代码 public class Solution { // y…

    Linux 2023年6月11日
    0139
  • linux自动备份mysql数据库

    备份脚本记录一下–(单个数据库) 2021-11-15 1.新建shell脚本:vim **.sh #!/bin/bashCKUP=/data/backup/db #获…

    Linux 2023年5月27日
    0127
  • 剪贴板被占用导致应用使用剪贴板拷贝内容失败抛出 COMException 0x800401D0 错误

    本文记录某些软件,例如 向日葵远程控制 软件占用剪贴板,导致 WPF 应用使用剪贴板拷贝内容和设置剪贴板时,抛出 System.Runtime.InteropServices.CO…

    Linux 2023年6月6日
    0135
  • Java 集合框架

    一、 Collection集合 1.1 集合概述 集合:集合是java中提供的一种容器,可以用来存储多个数据。 数组的长度是固定的。集合的长度是可变的。 数组中存储的是同一类型的元…

    Linux 2023年6月7日
    082
  • Linux CURL的安装和使用

    –获得安装包,从网上直接下载或者其他途径,这里直接wgetwget http://curl.haxx.se/download/curl-7.17.1.tar.gz&#8…

    Linux 2023年6月13日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球