Python subprocess模块的高级玩法

Python的subprocess模块是一个非常强大的工具,用于启动和与外部进程进行交互。它允许执行外部命令、访问系统Shell、管道数据、捕获输出和错误信息,以及更多。

本文详细介绍 subprocess模块的各个方面,包括如何执行外部命令、传递参数、处理输入输出、错误处理以及一些高级应用。

1. 介绍

subprocess模块是Python的标准库中的一部分,它允许与外部进程进行交互。这对于执行系统命令、调用其他可执行文件、处理数据流以及与其他进程通信非常有用。无论是需要执行简单的命令还是需要与复杂的外部程序进行交互,subprocess都可以胜任。

在接下来的内容中,我们将学习如何使用subprocess模块来执行外部命令、处理输入输出、捕获错误信息,并探讨一些高级用法。我们还会讨论一些安全性方面的注意事项,以确保您的程序不受到潜在的安全漏洞的威胁。

2. 执行外部命令

2.1 使用subprocess.run()

subprocess.run()是Python 3.5及更高版本引入的函数,用于运行外部命令并等待其完成。

以下是一个简单的示例,演示如何使用subprocess.run()来执行ls命令并获取其输出:

import subprocessresult = subprocess.run(["ls", "-l"], stdout=subprocess.PIPE, text=True)
print(result.stdout)

在上面的示例中,subprocess.run()接受一个包含命令及其参数的列表,通过stdout=subprocess.PIPE参数捕获标准输出,并使用text=True参数指定输出为文本。最后,我们打印了result.stdout以获取ls -l命令的输出。

2.2 使用subprocess.Popen()

subprocess.Popen()提供了更多的灵活性,允许与进程进行交互,而不仅仅是等待它完成。

以下是一个使用subprocess.Popen()的示例,演示如何执行外部命令并获取其输出:

import subprocess# 执行命令
process = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)# 读取标准输出和错误
out, err = process.communicate()print("标准输出:")
print(out)print("标准错误:")
print(err)

在上面的示例中,首先使用subprocess.Popen()来启动进程,并指定stdout=subprocess.PIPEstderr=subprocess.PIPE以捕获标准输出和标准错误。然后,使用process.communicate()方法来等待进程完成并获取其输出。

2.3 指定执行路径

使用cwd参数来指定执行外部命令的工作目录。例如,要在特定目录中执行命令,可以这样做:

import subprocessresult = subprocess.run(["ls", "-l"], stdout=subprocess.PIPE, text=True, cwd="/path/to/directory")
print(result.stdout)

这将在/path/to/directory目录中执行ls -l命令。

2.4 传递参数

如果命令需要接受参数,可以将它们作为列表的一部分传递给subprocess.run()subprocess.Popen()

例如,要将文件名作为参数传递给命令,可以这样做:

import subprocessfilename = "example.txt"
result = subprocess.run(["cat", filename], stdout=subprocess.PIPE, text=True)
print(result.stdout)

这将执行cat example.txt命令,其中filename是文件名。

3. 处理输入输出

3.1 标准输入

subprocess模块还可以将数据传递给外部命令的标准输入。要实现这一点,可以使用stdin参数,并将其设置为一个文件对象或一个字节串。

import subprocessinput_data = "Hello, subprocess!"
result = subprocess.run(["grep", "subprocess"], input=input_data, stdout=subprocess.PIPE, text=True)
print(result.stdout)

在上面的示例中,使用input_data将数据传递给grep命令的标准输入,并搜索包含"subprocess"的行。

3.2 标准输出

前面的示例中,已经看到如何捕获外部命令的标准输出。通过使用stdout参数,可以将标准输出重定向到文件、字节串或文件对象。

import subprocessoutput_file = open("output.txt", "w")
result = subprocess.run(["ls", "-l"], stdout=output_file, text=True)
output_file.close()

在上面的示例中,我们将ls -l命令的标准输出重定向到一个名为output.txt的文件。

3.3 标准错误

与标准输出类似,subprocess还可以捕获标准错误信息。要捕获标准错误,请使用stderr参数。

import subprocessresult = subprocess.run(["ls", "/nonexistent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print("标准输出:")
print(result.stdout)
print("标准错误:")
print(result.stderr)

在上面的示例中,执行ls /nonexistent命令,该命令会产生一个错误,并将标准输出和标准错误信息捕获到result.stdoutresult.stderr中。

4. 错误处理

执行外部命令时,通常需要处理错误。以下是一些处理错误的常用方法:

4.1 检查返回码

subprocess.run()subprocess.Popen()返回一个CompletedProcessPopen对象,其中包含有关命令执行的信息,包括返回码。返回码为0表示命令成功执行,非零返回码表示发生错误。

import subprocessresult = subprocess.run(["ls", "/nonexistent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:print("命令执行失败。")print("标准错误:")print(result.stderr)

在上面的示例中,检查result.returncode是否为0,如果不是,就表示命令执行失败。

4.2 捕获错误输出

有时,错误信息可能不仅仅包含在返回码中,还包含在标准错误输出中。可以捕获标准错误输出并检查其中的信息。

import subprocessresult = subprocess.run(["ls", "/nonexistent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:print("命令执行失败。")print("错误信息:")print(result.stderr)

在上面的示例中,我们捕获标准错误输出,并在发生错误时打印它。

5. 管道和重定向

subprocess还可以创建管道,将一个命令的输出连接到另一个命令的输入。这在处理复杂的数据处理任务时非常有用。

例如,要将一个命令的输出传递给另一个命令,可以这样做:

import subprocess# 创建第一个命令的进程
process1 = subprocess.Popen(["ls", "/path/to/directory"], stdout=subprocess.PIPE, text=True)# 创建第二个命令的进程,将第一个命令的输出连接到它的输入
process2 = subprocess.Popen(["grep", "search_term"], stdin=process1.stdout, stdout=subprocess.PIPE, text=True)# 从第二个命令的标准输出中读取结果
result = process2.communicate()[0]
print(result)

在上面的示例中,首先创建第一个命令的进程,然后创建第二个命令的进程,并将第一个命令的输出连接到第二个命令的输入。

6. 高级应用

6.1 同时读写标准输入输出

subprocess模块同时读取和写入标准输入和输出。这对于与外部进程进行双向通信非常有用。

以下是一个示例,演示如何使用subprocess进行双向通信:

import subprocess# 创建命令进程
process = subprocess.Popen(["python", "-u"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, universal_newlines=True)# 写入数据到标准输入
process.stdin.write("print('Hello from child process')\n")
process.stdin.flush()# 读取并打印标准输出
output, errors = process.communicate()
print("标准输出:")
print(output)# 打印标准错误
print("标准错误:")
print(errors)

在上面的示例中,创建了一个子进程,然后向其标准输入写入Python代码,并捕获其标准输出和标准错误。

6.2 超时处理

subprocess还允许您设置执行命令的超时时间,以防止命令运行时间过长。要实现这一点,您可以使用timeout参数。

例如:

import subprocesstry:result = subprocess.run(["sleep", "10"], timeout=5, stdout=subprocess.PIPE, text=True)print(result.stdout)
except subprocess.TimeoutExpired:print("命令执行超时。")

在上面的示例中,试图运行sleep 10命令,但由于设置了5秒的超时时间,当命令运行时间超过5秒时,将引发subprocess.TimeoutExpired异常。

6.3 使用Shell命令

默认情况下,subprocess不会使用Shell来执行命令。这是出于安全考虑,以防止潜在的Shell注入攻击。但有些情况下,可能需要使用Shell来执行命令,可以将shell参数设置为True

import subprocess# 使用Shell执行命令
result = subprocess.run("ls -l | grep .txt", shell=True, stdout=subprocess.PIPE, text=True)
print(result.stdout)

在上面的示例中,我们使用Shell来执行ls -l | grep .txt命令。

7. 安全性注意事项

在执行外部命令时,请务必小心处理输入,以防止潜在的安全漏洞。避免将不受信任的数据传递给subprocess,以免受到命令注入攻击。

确保了解正在执行的命令及其参数,以避免潜在的风险。

总结

Python的subprocess模块提供了强大的工具,允许与外部进程进行交互。可以使用它执行外部命令、传递参数、处理输入输出和错误信息,以及支持管道和重定向。这为编写需要与外部程序进行通信的Python应用程序提供了关键的功能。

subprocess模块是Python中处理外部进程交互的重要工具,但在使用时需要注意安全性问题,特别是在处理不受信任的输入时。熟练掌握这一模块,将有助于编写更强大和安全的Python应用程序,能够与外部程序进行有效通信。

相关内容拓展:(技术前沿)


近 10 年间,甚至连传统企业都开始大面积数字化时,我们发现开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。
针对这类问题,低代码把某些重复出现的场景、流程,具象化成一个个组件、api、数据库接口,避免了重复造轮子。极大的提高了程序员的生产效率。
介绍一款程序员都应该知道的软件 JNPF 快速开发平台,基于 Java/.Net 双技术引擎,专注于低代码,采用业内领先的 SpringBoot 微服务架构、支持 SpringCloud 模式,完善了平台的扩增基础,满足了系统快速开发、灵活拓展、无缝集成和高性能应用等综合能力;采用前后端分离模式,前端和后端的开发人员可分工合作负责不同板块,省事又便捷。
免费体验官网:www.jnpfsoft.com/?csdn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/186223.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis安装和部署详细流程

文章目录 一、Windows环境下安装 Redis1.1 下载Redis1.2 启动redis服务器1.3 启动redis客户端1.4 配置环境变量 参考资料 一、Windows环境下安装 Redis windows系统环境下,redis安装方式主要有: zip压缩包方式 https://redis.io/download 或者 https:/…

MMdetection3.0 问题

MMdetection3.0 问题 希望各位路过的大佬指教一下: 问题: 1、NWPU-VHR-10有标注的数据一共650张,我将其分为了455张训练集,195张验证集。 2、然后使用MMdetection3.0框架中的Faster-rcnn网络进行训练,设置训练参数b…

CityEngine2023 根据shp数据构建三维模型并导入UE5

目录 0 引言1 基本操作2 实践2.1 导入数据(.shp)2.2 构建三维模型2.3 将模型导入UE5 🙋‍♂️ 作者:海码007📜 专栏:CityEngine专栏💥 标题:CityEngine2023 根据shp数据构建三维模型…

Android问题笔记四十九:ViewPager 嵌套 Fragment 扩大滑动响应区域,避免左右滑动过于灵敏问题

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分…

finebi 新手入门案例

finebi 新手入门案例 连锁超市销售数据分析 步骤: 准备公共数据新建分析主题处理数据在数据中分析在图形中分析数据大屏 准备公共数据 点击公共数据 点击新建文件夹 修改文件夹名称 上传数据 鼠标悬停在文件夹上,右侧出现 鼠标悬停在文件夹上&#x…

git-5

1.GitHub为什么会火? 2.GitHub都有哪些核心功能? 3.怎么快速淘到感兴趣的开源项目 github上面开源项目非常多,为了我们高效率的找到我们想要的资源 根据时间 不进行登录,是没有办法享受到高级搜索中的代码功能的,登录…

maven 基础

maven常用命令 clean &#xff1a;清理 compile&#xff1a;编译 test&#xff1a;测试 package&#xff1a;打包 install&#xff1a;安装 maven坐标书写规范 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</ar…

改变生活,引领未来

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经深入到我们生活的各个角落&#xff0c;成为我们日常生活中不可或缺的一部分。它像一位魔术师&#xff0c;用其独特的“魔法”帮助我们解决问题、提供建议&#xff0c;甚至预测未来。本文将探讨人工智能如…

(Error Creating bean with name ‘xxx‘)类问题解决思路

学习springboot报错&#xff1a; Error creating bean with name com.atguigu.mybatislearning.MyBatisPlusServiceTest: Unsatisfied dependency expressed through field userService; 解决方式&#xff1a; 1、注解问题&#xff1a; Controller、service层的注解缺失会造…

链表中倒数第k个节点,剑指offer,力扣

目录 题目地址&#xff1a; 剑指offer原题&#xff1a; 我们直接看题解吧&#xff1a; 解题方法&#xff1a; 难度分析&#xff1a; 审题目事例提示&#xff1a; 解题思路&#xff08;双指针&#xff08;快慢指针&#xff09;&#xff09;&#xff1a; 代码实现&#xff1a; 代…

从功能测试到自动化测试,我总结了一些工作经验分享给大家

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

【驱动】SPI驱动分析(三)-SPI关键数据类型

SPI数据类型 SPI控制器驱动结构体 struct spi_master抽象了控制器硬件&#xff0c;在SoC中的指的就是内部SPI控制器&#xff0c;当向SPI核心层注册一个SPI控制器时就需要提供这样的一个结构体变量。它的定义在 include/linux/spi/spi.h 文件&#xff0c;如下&#xff1a; /*…

python高级练习题库实验1(A)部分

文章目录 题目1代码实验结果题目2代码实验结果题目3代码实验结果题目4代码实验结果题目总结题目1 输入一个整数,用于控制输出*的个数,输入日期,按照特定格式输出 研究下面的例子,并编写一个与这些例子完全相同的程序。 代码 import datetime# ask user for length of b…

(C++20) consteval立即函数

文章目录 由来consteval立即函数上下文的常量性质lambda表达式 编译期间确定无法获取函数指针查看汇编 END 由来 在C11中推出了constexpr使得对象或者函数能够具有常量性质并能在编译器确定。但是对于constexpr修饰的函数来说&#xff0c;无法保证严格的在编译器确定。 下面这…

咨询+低代码,强强联合为制造业客户赋能

内容来自演讲&#xff1a;沈毅 | 遨睿智库 | 董事长 & 王劭禹 | 橙木智能 | 联合创始人 摘要 文章主要讲述了智库董事长沈毅创办广告公司的经历&#xff0c;以及他在管理公司过程中遇到的问题和挑战&#xff0c;最后通过与明道云以及橙木智能联合创始人王邵禹老师的合作&…

【驱动】SPI驱动分析(四)-关键API解析

关键API 设备树 设备树解析 我们以Firefly 的SPI demo 分析下dts中对spi的描述&#xff1a; /* Firefly SPI demo */ &spi1 {spi_demo: spi-demo00{status "okay";compatible "firefly,rk3399-spi";reg <0x00>;spi-max-frequency <48…

当内核有内存泄漏的时候

内存泄露是一个很容易出现的问题&#xff0c;尤其是对于测试不太充分的代码。怎么判断出现内存泄露了呢&#xff1f;很简单&#xff0c;就跑一些简单的测试&#xff0c;等待足够长时间即可。内存总有耗尽的时候&#xff0c;这时候内核会触发OOM&#xff0c;根据oom_score选择一…

【驱动】SPI驱动分析(六)-RK SPI驱动分析

前言 Linux的spi接口驱动实现目录在kernel\drivers\spi下。这个目录和一些层次比较明显的驱动目录布局不同&#xff0c;全放在这个文件夹下&#xff0c;因此还是只好通过看Kconfig 和 Makefile来找找思路 先看Makefile&#xff0c;里面关键几行&#xff1a; obj-$(CONFIG_SPI…

【C++ Primer Plus学习记录】循环和文本输入

目录 1.使用原始的cin进行输入 2.使用cin.get(char)进行补救 3.使用哪一个cin.get() 4.文件尾条件 循环完后的一项最常见、最重要的任务&#xff1a;逐字符地读取来自文件或键盘的文本。 cin对象支持3种不同模式的单字符输入&#xff0c;其用户接口各不相同。下面介绍如何…

形态学操作—底帽运算

底帽运算&#xff08;Bottom-hat transformation&#xff09;&#xff0c;也称为黑帽运算&#xff0c;是形态学图像处理中的一种操作。它与顶帽运算相反&#xff0c;通过闭运算的结果与原始图像的差异来突出图像中的暗区域特征。 原理 底帽运算通过对图像执行闭运算&#xff0…