ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python subprocess的使用

2022-01-23 22:02:02  阅读:223  来源: 互联网

标签:None shell stdout Python Popen subprocess stderr 使用


前言

部门内部存在大量代码使用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)

执行结果:

标签:None,shell,stdout,Python,Popen,subprocess,stderr,使用
来源: https://www.cnblogs.com/dennis-wong/p/15811860.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有