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)

大家都在看

  • shell之磁盘容量检查,配合crontab可以定时清理磁盘

    我的做法: !/bin/bashAvailable=df -k | sed -n 2p | awk ‘{print $4}’if [ $Available -eq 0 ];then…

    Linux 2023年5月28日
    073
  • Docker部署Dotnet

    方法一:打包+镜像 部署 将要部署的项目及其依赖的项目上传至指定文件夹下 要部署的项目添加Docker支持,生成Dockerfile文件 将生成的Dockerfile文件上传至要部…

    Linux 2023年6月13日
    0105
  • SSH加密原理

    1、SSH初次交换公钥 客户端发起链接请求 服务端返回自己的公钥,以及一个会话ID(这一步客户端得到服务端公钥) 客户端生成密钥对 客户端用自己的公钥异或会话ID,计算出一个值Re…

    Linux 2023年6月7日
    083
  • 最简单的,在win,linux中,用powershell,自动获取Let’s Encrypt证书方法

    powershell传教士原创 2020-04-12,2022-05更新 Let’s Encrypt证书有效期3个月,支持泛域名【*.你的网站.net】。支持n天内(一…

    Linux 2023年6月14日
    092
  • Linux目录结构

    一、基本介绍 linux文件系统采用级层的树状目录结构,最上层的就是根目录 / ,在此基础上创建其他目录。在linux中一切皆为文件 二、详细目录介绍 /bin(不可随意更改):该…

    Linux 2023年6月6日
    0126
  • 高等代数:1 线性方程组的解法

    1 线性方程组的解法 1、线性方程组:左端为未知量x的一次齐次式,右端是常数。关键词:系数、常数项、n元线性方程组、解集 2、线性方程组的初等变换:1)把一个方程的倍数加到另一个方…

    Linux 2023年6月8日
    099
  • Redis-Sentinel Redis的哨兵模式

    Redis-Sentinel Redis的哨兵模式Redis Sentinel 模式简介Redis-Sentinel是官方推荐的高可用解决方案,当redis在做master-sla…

    Linux 2023年5月28日
    086
  • rpm简单使用

    rpm描述:利用源码包编译成rpm时,会去指定安装好这个包的位置本质:解压,然后拷贝到相关的目录,然后执行脚本 查询所有已经安装过的包 查看安装位置 解压rpm 查看脚本 查看配置…

    Linux 2023年6月7日
    068
  • bash获取机器IP后缀

    1.先获取部分数据 ip_0=ip a | grep inet | grep -v inet6 | grep ens | awk ‘NR==1{print $2}’ | cut -…

    Linux 2023年6月7日
    087
  • Linux安装管理

    Linux系列 包管理工具 单个软件包 管理工具 RedHat系列 Redhat Centos Fedora yum rpm .rpm Debian系列 Ubuntu apt-ge…

    Linux 2023年6月8日
    086
  • GDT表实现

    GDT是保护模式下的内存段登记表。 段界限计算 段界限用 20 个二进制位来表示。只不过此段界限只是个单位量,它的单位要么是字节,要么是 4K,这是由描述符中的G位来指 定的。由于…

    Linux 2023年6月7日
    075
  • archLinux 配置用户

    archlinux 启动之后只有默认的root用户,首先介绍下系统启动到登录需要的步骤 1.系统通过systemd 以pid为1初始化系统,启动系统用户和系统必要的服务,(这一步目…

    Linux 2023年6月13日
    075
  • DNS

    DNS是域名系统(Domain Name System),简单来说就是平时上网输入的URL,如 www.baidu.com 就是域名,而DNS就是将这个域名解析成IP地址,如 ww…

    Linux 2023年6月7日
    075
  • 快速删除指定文件夹下的.DS_Store文件

    清除当前文件夹中 .DS_store 文件: find "." -name .DS_Store find "." -name .DS_Sto…

    Linux 2023年6月14日
    067
  • 【翻译】如何编写 Git 提交消息

    个人博客及创作索引页正在制作中,此处仅释出本地第一大版本。原文档基于 Hexo 及相关插件,不兼容于此处的格式暂不统一修复。 《【翻译】如何编写 Git 提交消息》[1]的简体中文…

    Linux 2023年6月13日
    0101
  • muduo项目介绍

    在上一个集群聊天服务器项目中,我使用了 muduo作为网络库,然后主要实现了业务逻辑等,所以为了深入网络库的代码和实现,我跟着一位老师的代码去实现了 muduo库的基本原理和作用,…

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