Python 进程调用(subprocess)的实现

 更新时间:2025年10月31日 09:47:34   作者:cliffordl  
在Python编程中,subprocess库是一个功能强大的工具,它允许我们创建新进程、连接到其输入/输出/错误管道,并获取其返回代码,下面就来详细的介绍一下,感兴趣的可以了解一下

1. 概述

1.1. subprocess 简介

在 Python 编程中,subprocess 库是一个功能强大的工具,它允许我们创建新进程、连接到其输入/输出/错误管道,并获取其返回代码。

1.2. subprocess 库的功能

subprocess 库提供了多种功能,以满足不同的需求。主要功能包括:

  • 运行外部命令: 可以执行系统命令或调用其他可执行文件。
  • 交互式进程通信: 启动外部进程,并通过管道与其进行交互,发送输入并获取输出。
  • 管道和重定向: 创建一个进程的输出作为另一个进程的输入,或重定向进程的输出到文件。
  • 进程管理: 监控进程状态,等待进程结束,或终止进程。

2. 应用场景及示例

2.1. 运行外部命令

subprocess.run() 是一个高级接口,用于执行外部命令并等待其完成。它返回一个 CompletedProcess 对象,包含执行结果的相关信息。

import subprocess
import sys

def run_command_safely(command):
    """安全运行命令,处理Windows和Unix的差异"""
    try:
        if sys.platform == 'win32':
            # Windows 需要特殊处理
            result = subprocess.run(command, shell=True, capture_output=True, text=True, encoding='gbk')
        else:
            # Unix/Linux/Mac
            result = subprocess.run(command, capture_output=True, text=True)
        return result
    except Exception as e:
        return subprocess.CompletedProcess(command, 1, '', str(e))
    
result = run_command_safely(['ls'])
# # 执行外部命令并捕获输出
print("Return Code:", result.returncode)
print("Standard Output:", result.stdout)
print("Standard Error:", result.stderr)

capture_output=True:捕获子进程的标准输出和标准错误。
text=True:以文本模式处理输入/输出。

2.2. 交互式进程通信

subprocess.Popen() 提供了更灵活的方式来管理子进程,可以通过管道发送输入数据给子进程,并获取其输出。

import subprocess
import sys

def basic_popen(command):
    """基本Popen使用"""
    try:
        if sys.platform == 'win32':
            # 执行dir命令
            result = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding='gbk')
        else:
            result = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
    except Exception as e:
        return subprocess.CompletedProcess(command, 1, '', str(e))
    # 等待进程完成并获取输出
    stdout, stderr = result.communicate()
    # return result
    
    print(f"返回码: {result.returncode}")
    print(f"输出:\n{stdout}")
    if stderr:
        print(f"错误:\n{stderr}")

basic_popen(['dir'])

[‘dir’]:要执行的命令和参数。
stdin=subprocess.PIPE:通过管道向子进程发送数据。
stdout=subprocess.PIPE:通过管道捕获子进程的输出。
process.communicate(input=‘some input data\n’):向子进程发送输入数据并获取输出。

2.3. 管道和重定向

subprocess 库可以轻松创建管道,将一个进程的输出重定向到另一个进程的输入。

import subprocess

# 第一个命令
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
# 第二个命令,通过管道传输数据
p2 = subprocess.Popen(['grep', '.py'], stdin=p1.stdout, stdout=subprocess.PIPE)
output = p2.communicate()[0]
print('Python文件列表:')
print(output.decode())

p1.stdout=subprocess.PIPE:将p1的输出作为管道。
p2.stdin=p1.stdout:将p1的输出作为p2的输入。
p2.communicate():获取p2的最终输出。

2.4. 进程管理

subprocess.Popen() 还提供了多种方法来管理进程,如poll()、terminate()、kill()等。

import subprocess
import sys

def run_command_safely(command):
    """安全运行命令,处理Windows和Unix的差异"""
    try:
        if sys.platform == 'win32':
            # Windows 需要特殊处理
            result = subprocess.Popen(command, shell=True, text=True, encoding='gbk')
        else:
            # Unix/Linux/Mac
            result = subprocess.Popen(command)
        
        # 检查进程是否仍在运行
        print("Process is running:", result.poll() is None)
        # 终止进程
        result.terminate()
        # 等待进程结束
        result.wait()
        print("Process has terminated")
    except Exception as e:
        print("Exception", str(e))
        return subprocess.CompletedProcess(command, 1, '', str(e))
    
# 启动一个子进程
run_command_safely(['sleep', '10'])

process.poll():检查进程是否仍在运行,返回None表示仍在运行,返回退出码表示已结束。
process.terminate():请求终止进程。
process.wait():等待进程结束。

3. 与 os.system 和 os.popen 对比

虽然 os.system 和 os.popen 也可以用于执行外部命令并与进程进行交互,但它们与 subprocess 相比存在一些限制和不足。

3.1. os.system

os.system 是 Python 中最简单的执行外部命令的方法,但它有几个显著的缺点:
无法捕获输出: os.system 只能执行命令,无法直接捕获其输出或错误。输出会直接打印到控制台。
返回码有限: 它返回一个8位的字节,表示命令的退出状态,这可能导致状态码被截断。
安全性问题: 使用字符串拼接来构建命令可能会导致安全风险,如命令注入。

import os

# 执行外部命令
exit_code = os.system('dir')
print("Exit Code:", exit_code)

3.2. os.popen

os.popen 允许我们打开一个与命令的管道,从中读取输出。与 os.system 相比,它可以捕获输出,但仍然有一些限制:
单向通信: 它只能用于从命令读取输出,不能发送输入。
资源管理: 需要手动关闭文件对象,否则可能导致资源泄漏。
安全性问题: 同样存在命令注入的风险。

import os

# 打开一个与命令的管道并读取输出
process = os.popen('dir')
output = process.read()
process.close()
print("Output:", output)

3.3. subprocess 的优势

与 os.system 和 os.popen 相比,subprocess 提供了以下优势:
更强大的功能: 支持双向通信、管道、重定向等高级功能。
更好的资源管理: 可以自动管理文件描述符和进程,减少资源泄漏的风险。
更高的安全性: 通过列表形式传递命令和参数,避免了命令注入的风险。
更丰富的返回信息: subprocess.run() 返回一个 CompletedProcess 对象,包含退出码、输出和错误等信息。

到此这篇关于Python 进程调用(subprocess)的实现的文章就介绍到这了,更多相关Python 进程调用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python绘制折线图和条形图的方法

    python绘制折线图和条形图的方法

    这篇文章主要为大家详细介绍了python实现折线图和条形图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Python使用re模块实现okenizer(表达式分词器)

    Python使用re模块实现okenizer(表达式分词器)

    这篇文章主要介绍了Python使用re模块实现okenizer,我们这里讲解用正则表达式构建简单的表达式分词器(tokenizer),它能够将表达式字符串从左到右解析为标记(tokens)流,需要的朋友可以参考下
    2022-04-04
  • python协程异步IO中asyncio的使用

    python协程异步IO中asyncio的使用

    这篇文章主要介绍了python异步编程之asyncio的使用,python中异步IO操作是通过asyncio来实现的,为了更加详细说明asyncio,我们先从协程的最基础开始讲解
    2023-12-12
  • Django Rest framework之权限的实现示例

    Django Rest framework之权限的实现示例

    这篇文章主要介绍了Django Rest framework之权限的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • Python flask框架如何显示图像到web页面

    Python flask框架如何显示图像到web页面

    这篇文章主要介绍了Python flask框架如何显示图像到web页面,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Python入门篇之对象类型

    Python入门篇之对象类型

    本章中我们将讲述Python的对象类型,包括数字、整型、布尔型、长整形、浮点型、复数型、字符串、列表、元组、字典等。
    2014-10-10
  • 如何在Python中实现goto语句的方法

    如何在Python中实现goto语句的方法

    这篇文章主要介绍了如何在Python中实现goto语句的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • python单例模式原理与创建方法实例分析

    python单例模式原理与创建方法实例分析

    这篇文章主要介绍了python单例模式原理与创建方法,结合实例形式分析了Python单例模式的概念、原理、定义、使用方法及相关操作注意事项,需要的朋友可以参考下
    2019-10-10
  • python OpenCV计算图片相似度的5种算法

    python OpenCV计算图片相似度的5种算法

    本文主要介绍了python OpenCV计算图片相似度的5种算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Python利用psutil库进行监控进程和资源

    Python利用psutil库进行监控进程和资源

    psutil是Python系统和进程工具库,它提供了一种跨平台的方式来获取系统信息、管理系统进程、监控系统性能、操作系统资源等,下面就跟随小编一起来学习psutil库的具体应用吧
    2024-01-01

最新评论